1
0
Fork 0

NavDisplay - cache nearby positioned items, and fix symbol instance queue to be cleared each update. Works much more sanely now.

This commit is contained in:
James Turner 2011-11-07 19:40:30 +00:00
parent 81bb67bc24
commit 10e6cc016b
2 changed files with 85 additions and 28 deletions

View file

@ -145,6 +145,22 @@ static osg::Vec2 mult(const osg::Vec2& v, const osg::Matrixf& m)
return osg::Vec2(r.x(), r.y());
}
class NavDisplay::CacheListener : public SGPropertyChangeListener
{
public:
CacheListener(NavDisplay *nd) :
_nd(nd)
{}
virtual void valueChanged (SGPropertyNode * prop)
{
_nd->invalidatePositionedCache();
SG_LOG(SG_INSTR, SG_INFO, "invalidating NavDisplay cache");
}
private:
NavDisplay* _nd;
};
///////////////////////////////////////////////////////////////////
class SymbolDef
@ -381,8 +397,14 @@ NavDisplay::~NavDisplay()
void
NavDisplay::init ()
{
_cachedItemsValid = false;
_cacheListener.reset(new CacheListener(this));
_serviceable_node = _Instrument->getNode("serviceable", true);
_rangeNode = _Instrument->getNode("range", true);
_rangeNode->setDoubleValue(40.0);
_rangeNode->addChangeListener(_cacheListener.get());
// texture name to use in 2D and 3D instruments
_texture_path = _Instrument->getStringValue("radar-texture-path",
"Aircraft/Instruments/Textures/od_wxradar.rgb");
@ -402,11 +424,6 @@ NavDisplay::init ()
_odg = (FGODGauge *)imgr->get_subsystem("od_gauge");
_odg->setSize(_Instrument->getIntValue("texture-size", 512));
_user_lat_node = fgGetNode("/position/latitude-deg", true);
_user_lon_node = fgGetNode("/position/longitude-deg", true);
_user_alt_node = fgGetNode("/position/altitude-ft", true);
_route = static_cast<FGRouteMgr*>(globals->get_subsystem("route-manager"));
_navRadio1Node = fgGetNode("/instrumentation/nav[0]", true);
@ -508,7 +525,7 @@ NavDisplay::update (double delta_time_sec)
}
_time -= _updateInterval;
_rangeNm = _Instrument->getFloatValue("range", 40.0);
_rangeNm = _rangeNode->getFloatValue();
if (_Instrument->getBoolValue("aircraft-heading-up", true)) {
_view_heading = fgGetDouble("/orientation/heading-deg");
} else {
@ -527,9 +544,17 @@ NavDisplay::update (double delta_time_sec)
_projectMat = osg::Matrixf::scale(_scale, _scale, 1.0) *
degRotation(-_view_heading) * _centerTrans;
_pos = SGGeod::fromDegFt(_user_lon_node->getDoubleValue(),
_user_lat_node->getDoubleValue(),
_user_alt_node->getDoubleValue());
_pos = globals->get_aircraft_position();
// invalidate the cache of positioned items, if we travelled more than 1nm
if (_cachedItemsValid) {
SGVec3d cartNow(SGVec3d::fromGeod(_pos));
double movedNm = dist(_cachedPos, cartNow) * SG_METER_TO_NM;
_cachedItemsValid = (movedNm < 1.0);
if (!_cachedItemsValid) {
SG_LOG(SG_INSTR, SG_INFO, "invalidating NavDisplay cache due to moving: " << movedNm);
}
}
_vertices->clear();
_lineVertices->clear();
@ -538,6 +563,11 @@ NavDisplay::update (double delta_time_sec)
_texCoords->clear();
_textGeode->removeDrawables(0, _textGeode->getNumDrawables());
BOOST_FOREACH(SymbolInstance* si, _symbols) {
delete si;
}
_symbols.clear();
BOOST_FOREACH(SymbolDef* def, _rules) {
if (def->enable) {
def->enabled = def->enable->test();
@ -787,15 +817,17 @@ public:
void NavDisplay::findItems()
{
Filter filt;
filt.minRunwayLengthFt = 2000;
FGPositioned::List items =
FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
FGPositioned::List::const_iterator it;
for (it = items.begin(); it != items.end(); ++it) {
foundPositionedItem(*it);
if (!_cachedItemsValid) {
SG_LOG(SG_INSTR, SG_INFO, "re-validating NavDisplay cache");
Filter filt;
filt.minRunwayLengthFt = 2000;
_itemsInRange = FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
_cachedItemsValid = true;
_cachedPos = SGVec3d::fromGeod(_pos);
}
BOOST_FOREACH(FGPositioned* pos, _itemsInRange) {
foundPositionedItem(pos);
}
}
@ -1118,11 +1150,26 @@ void NavDisplay::computeAIStates(const SGPropertyNode* ai, string_set& states)
}
}
void NavDisplay::addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars)
bool NavDisplay::addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars)
{
if (isProjectedClipped(proj)) {
return false;
}
SymbolInstance* sym = new SymbolInstance(proj, heading, def, vars);
_symbols.push_back(sym);
return true;
}
bool NavDisplay::isProjectedClipped(const osg::Vec2& projected) const
{
double size = _odg->size();
return (projected.x() < 0.0) ||
(projected.y() < 0.0) ||
(projected.x() >= size) ||
(projected.y() >= size);
}

View file

@ -34,11 +34,13 @@
#include <vector>
#include <string>
#include <memory>
#include <Navaids/positioned.hxx>
class FGODGauge;
class FGRouteMgr;
class FGNavRecord;
class FGPositioned;
class SymbolInstance;
class SymbolDef;
@ -61,6 +63,10 @@ public:
virtual void init();
virtual void update(double dt);
void invalidatePositionedCache()
{
_cachedItemsValid = false;
}
protected:
std::string _name;
int _num;
@ -70,11 +76,7 @@ protected:
SGPropertyNode_ptr _serviceable_node;
SGPropertyNode_ptr _Instrument;
SGPropertyNode_ptr _radar_mode_control_node;
SGPropertyNode_ptr _user_lat_node;
SGPropertyNode_ptr _user_lon_node;
SGPropertyNode_ptr _user_heading_node;
SGPropertyNode_ptr _user_alt_node;
FGODGauge *_odg;
@ -103,11 +105,11 @@ private:
bool anyRuleMatches(const std::string& type, const string_set& states) const;
void findRules(const std::string& type, const string_set& states, SymbolDefVector& rules);
void addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars);
bool addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars);
void addLine(osg::Vec2 a, osg::Vec2 b, const osg::Vec4& color);
osg::Vec2 projectBearingRange(double bearingDeg, double rangeNm) const;
osg::Vec2 projectGeod(const SGGeod& geod) const;
bool isProjectedClipped(const osg::Vec2& projected) const;
void updateFont();
std::string _texture_path;
@ -154,13 +156,21 @@ private:
FGRouteMgr* _route;
SGGeod _pos;
double _rangeNm;
SGPropertyNode_ptr _rangeNode;
SymbolDefVector _rules;
FGNavRecord* _nav1Station;
FGNavRecord* _nav2Station;
std::vector<SymbolInstance*> _symbols;
std::set<FGPositioned*> _routeSources;
bool _cachedItemsValid;
SGVec3d _cachedPos;
FGPositioned::List _itemsInRange;
SGPropertyNode_ptr _excessDataNode;
class CacheListener;
std::auto_ptr<CacheListener> _cacheListener;
};
#endif // _INST_ND_HXX