]> git.mxchange.org Git - flightgear.git/blobdiff - src/Instrumentation/wxradar.cxx
NavDisplay enhancements for Syd.
[flightgear.git] / src / Instrumentation / wxradar.cxx
index 84d9f84fe4ec7adaac3308ad185cc50c3ffcee53..b1f81be656ebf2e293ba902f662e6331943a4990 100644 (file)
 
 #include <sstream>
 #include <iomanip>
+
 using std::stringstream;
 using std::endl;
 using std::setprecision;
 using std::fixed;
 using std::setw;
 using std::setfill;
+using std::string;
 
 #include <Main/fg_props.hxx>
 #include <Main/globals.hxx>
@@ -75,7 +77,6 @@ wxRadarBg::wxRadarBg(SGPropertyNode *node) :
     _interval(node->getDoubleValue("update-interval-sec", 1.0)),
     _elapsed_time(0),
     _persistance(0),
-    _sim_init_done(false),
     _odg(0),
     _range_nm(0),
     _scale(0),
@@ -118,6 +119,7 @@ wxRadarBg::wxRadarBg(SGPropertyNode *node) :
 wxRadarBg::~wxRadarBg ()
 {
     _font_node->removeChangeListener(this);
+    delete _odg;
 }
 
 
@@ -125,6 +127,7 @@ void
 wxRadarBg::init ()
 {
     _serviceable_node = _Instrument->getNode("serviceable", true);
+    _sceneryLoaded = fgGetNode("/sim/sceneryloaded", true);
 
     // texture name to use in 2D and 3D instruments
     _texture_path = _Instrument->getStringValue("radar-texture-path",
@@ -153,8 +156,7 @@ wxRadarBg::init ()
     // input range = n nm (20/40/80)
     // input display-mode = arc | rose | map | plan
 
-    FGInstrumentMgr *imgr = (FGInstrumentMgr *)globals->get_subsystem("instrumentation");
-    _odg = (FGODGauge *)imgr->get_subsystem("od_gauge");
+    _odg = new FGODGauge;
     _odg->setSize(512);
 
     _ai_enabled_node = fgGetNode("/sim/ai/enabled", true);
@@ -285,22 +287,17 @@ osg::Matrixf wxRotate(float angle)
 void
 wxRadarBg::update (double delta_time_sec)
 {
-    if (!_sim_init_done) {
-        if (!fgGetBool("sim/sceneryloaded", false))
-            return;
+    if (!_sceneryLoaded->getBoolValue())
+        return;
 
-        _sim_init_done = true;
-    }
     if (!_odg || !_serviceable_node->getBoolValue()) {
         _Instrument->setStringValue("status", "");
         return;
     }
+
     _time += delta_time_sec;
-    if (_time < _interval){
-//        cout << "WXradar update too soon " << _time << endl;
+    if (_time < _interval)
         return;
-    }
-//        cout << "WXradar updating" << _time<< endl;
 
     _time = 0.0;
 
@@ -354,7 +351,7 @@ wxRadarBg::update (double delta_time_sec)
                 _radar_centre_node->setBoolValue(false);
             }
 
-            //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: displacement "
+            //SG_LOG(SG_INSTR, SG_DEBUG, "Radar: displacement "
             //        << _x_offset <<", "<<_y_offset
             //        << " user_speed_east_fps * SG_FPS_TO_KT "
             //        << user_speed_east_fps * SG_FPS_TO_KT
@@ -378,90 +375,99 @@ wxRadarBg::update (double delta_time_sec)
         _texCoords->clear();
         _textGeode->removeDrawables(0, _textGeode->getNumDrawables());
 
+#if 0
+        //TODO FIXME Mask below (only used for ARC mode) isn't properly aligned, i.e.
+        // it assumes the a/c position at the center of the display - though it's somewhere at
+        // bottom part for ARC mode.
+        // The mask hadn't worked at all for a while (probably since the OSG port) due to
+        // another bug (which is fixed now). Now, the mask is disabled completely until s.o.
+        // adapted the coordinates below. And the mask is only really useful to limit displayed
+        // weather blobs (not support yet).
+        // Aircraft echos are already limited properly through wxradar's "limit-deg" property.
+        {
+            osg::DrawArrays *maskPSet
+                = static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(1));
+            osg::DrawArrays *trimaskPSet
+                = static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(2));
+
+            if (_display_mode == ARC) {
+                // erase what is out of sight of antenna
+                /*
+                |\     /|
+                | \   / |
+                |  \ /  |
+                ---------
+                |       |
+                |       |
+                ---------
+                */
+                float xOffset = 256.0f;
+                float yOffset = 200.0f;
+
+                int firstQuadVert = _vertices->size();
+                _texCoords->push_back(osg::Vec2f(0.5f, 0.25f));
+                _vertices->push_back(osg::Vec2f(-xOffset, 0.0 + yOffset));
+                _texCoords->push_back(osg::Vec2f(1.0f, 0.25f));
+                _vertices->push_back(osg::Vec2f(xOffset, 0.0 + yOffset));
+                _texCoords->push_back(osg::Vec2f(1.0f, 0.5f));
+                _vertices->push_back(osg::Vec2f(xOffset, 256.0 + yOffset));
+                _texCoords->push_back(osg::Vec2f(0.5f, 0.5f));
+                _vertices->push_back(osg::Vec2f(-xOffset, 256.0 + yOffset));
+                maskPSet->set(osg::PrimitiveSet::QUADS, firstQuadVert, 4);
+                firstQuadVert += 4;
+
+                // The triangles aren't supposed to be textured, but there's
+                // no need to set up a different Geometry, switch modes,
+                // etc. I happen to know that there's a white pixel in the
+                // texture at 1.0, 0.0 :)
+                float centerY = tan(30 * SG_DEGREES_TO_RADIANS);
+                _vertices->push_back(osg::Vec2f(0.0, 0.0));
+                _vertices->push_back(osg::Vec2f(-256.0, 0.0));
+                _vertices->push_back(osg::Vec2f(-256.0, 256.0 * centerY));
+
+                _vertices->push_back(osg::Vec2f(0.0, 0.0));
+                _vertices->push_back(osg::Vec2f(256.0, 0.0));
+                _vertices->push_back(osg::Vec2f(256.0, 256.0 * centerY));
+
+                _vertices->push_back(osg::Vec2f(-256, 0.0));
+                _vertices->push_back(osg::Vec2f(256.0, 0.0));
+                _vertices->push_back(osg::Vec2f(-256.0, -256.0));
+
+                _vertices->push_back(osg::Vec2f(256, 0.0));
+                _vertices->push_back(osg::Vec2f(256.0, -256.0));
+                _vertices->push_back(osg::Vec2f(-256.0, -256.0));
+
+                const osg::Vec2f whiteSpot(1.0f, 0.0f);
+                for (int i = 0; i < 3 * 4; i++)
+                    _texCoords->push_back(whiteSpot);
+
+                trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, firstQuadVert, 3 * 4);
+
+            } else
+            {
+                maskPSet->set(osg::PrimitiveSet::QUADS, 0, 0);
+                trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, 0, 0);
+            }
+
+            maskPSet->dirty();
+            trimaskPSet->dirty();
+        }
+#endif
 
-        update_weather();
+        // remember index of next vertex
+        int vIndex = _vertices->size();
 
+        update_weather();
 
         osg::DrawArrays *quadPSet
             = static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(0));
-        quadPSet->set(osg::PrimitiveSet::QUADS, 0, _vertices->size());
-        quadPSet->dirty();
-
-        // erase what is out of sight of antenna
-        /*
-        |\     /|
-        | \   / |
-        |  \ /  |
-        ---------
-        |       |
-        |       |
-        ---------
-        */
-
-        osg::DrawArrays *maskPSet
-            = static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(1));
-        osg::DrawArrays *trimaskPSet
-            = static_cast<osg::DrawArrays*>(_geom->getPrimitiveSet(2));
-
-        if (_display_mode == ARC) {
-            float xOffset = 256.0f;
-            float yOffset = 200.0f;
-
-            int firstQuadVert = _vertices->size();
-            _texCoords->push_back(osg::Vec2f(0.5f, 0.25f));
-            _vertices->push_back(osg::Vec2f(-xOffset, 0.0 + yOffset));
-            _texCoords->push_back(osg::Vec2f(1.0f, 0.25f));
-            _vertices->push_back(osg::Vec2f(xOffset, 0.0 + yOffset));
-            _texCoords->push_back(osg::Vec2f(1.0f, 0.5f));
-            _vertices->push_back(osg::Vec2f(xOffset, 256.0 + yOffset));
-            _texCoords->push_back(osg::Vec2f(0.5f, 0.5f));
-            _vertices->push_back(osg::Vec2f(-xOffset, 256.0 + yOffset));
-            maskPSet->set(osg::PrimitiveSet::QUADS, firstQuadVert, 4);
-
-            // The triangles aren't supposed to be textured, but there's
-            // no need to set up a different Geometry, switch modes,
-            // etc. I happen to know that there's a white pixel in the
-            // texture at 1.0, 0.0 :)
-            float centerY = tan(30 * SG_DEGREES_TO_RADIANS);
-            _vertices->push_back(osg::Vec2f(0.0, 0.0));
-            _vertices->push_back(osg::Vec2f(-256.0, 0.0));
-            _vertices->push_back(osg::Vec2f(-256.0, 256.0 * centerY));
-
-            _vertices->push_back(osg::Vec2f(0.0, 0.0));
-            _vertices->push_back(osg::Vec2f(256.0, 0.0));
-            _vertices->push_back(osg::Vec2f(256.0, 256.0 * centerY));
-
-            _vertices->push_back(osg::Vec2f(-256, 0.0));
-            _vertices->push_back(osg::Vec2f(256.0, 0.0));
-            _vertices->push_back(osg::Vec2f(-256.0, -256.0));
-
-            _vertices->push_back(osg::Vec2f(256, 0.0));
-            _vertices->push_back(osg::Vec2f(256.0, -256.0));
-            _vertices->push_back(osg::Vec2f(-256.0, -256.0));
-
-            const osg::Vec2f whiteSpot(1.0f, 0.0f);
-            for (int i = 0; i < 3 * 4; i++)
-                _texCoords->push_back(whiteSpot);
-
-            trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, firstQuadVert + 4, 3 * 4);
-
-        } else {
-            maskPSet->set(osg::PrimitiveSet::QUADS, 0, 0);
-            trimaskPSet->set(osg::PrimitiveSet::TRIANGLES, 0, 0);
-        }
-
-        maskPSet->dirty();
-        trimaskPSet->dirty();
-
-        // draw without mask
-        _vertices->clear();
-        _texCoords->clear();
 
         update_aircraft();
         update_tacan();
         update_heading_marker();
 
-        quadPSet->set(osg::PrimitiveSet::QUADS, 0, _vertices->size());
+        // draw all new vertices are quads
+        quadPSet->set(osg::PrimitiveSet::QUADS, vIndex, _vertices->size()-vIndex);
         quadPSet->dirty();
     }
 }
@@ -527,7 +533,7 @@ wxRadarBg::update_weather()
                     * wxRotate(angle) * _centerTrans);
                 addQuad(_vertices, _texCoords, m, texBase);
 
-                //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: drawing clouds"
+                //SG_LOG(SG_INSTR, SG_DEBUG, "Radar: drawing clouds"
                 //        << " ID=" << cloudId
                 //        << " x=" << x
                 //        << " y="<< y
@@ -906,7 +912,7 @@ wxRadarBg::update_tacan()
         * wxRotate(angle) * _centerTrans);
     addQuad(_vertices, _texCoords, m, texBase);
 
-    //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar:     drawing TACAN"
+    //SG_LOG(SG_INSTR, SG_DEBUG, "Radar:     drawing TACAN"
     //        << " dist=" << radius
     //        << " view_heading=" << _view_heading * SG_RADIANS_TO_DEGREES
     //        << " bearing=" << angle * SG_RADIANS_TO_DEGREES
@@ -929,7 +935,7 @@ wxRadarBg::update_heading_marker()
     m *= _centerTrans;
     addQuad(_vertices, _texCoords, m, texBase);
 
-    //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar:   drawing heading marker"
+    //SG_LOG(SG_INSTR, SG_DEBUG, "Radar:   drawing heading marker"
     //        << " x,y " << x <<","<< y
     //        << " dist" << dist
     //        << " view_heading" << _view_heading * SG_RADIANS_TO_DEGREES
@@ -978,7 +984,7 @@ wxRadarBg::withinRadarHorizon(double user_alt, double alt, double range_nm)
         alt = 0; // to allow some vertical extent of target
 
     double radarhorizon = 1.23 * (sqrt(alt) + sqrt(user_alt));
-//    SG_LOG(SG_GENERAL, SG_ALERT, "Radar: radar horizon " << radarhorizon);
+//    SG_LOG(SG_INSTR, SG_ALERT, "Radar: radar horizon " << radarhorizon);
     return radarhorizon >= range_nm;
 }
 
@@ -1006,7 +1012,7 @@ wxRadarBg::inRadarRange(double sigma, double range_nm)
         constant = 35;
 
     double maxrange = constant * pow(sigma, 0.25);
-    //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: max range " << maxrange);
+    //SG_LOG(SG_INSTR, SG_DEBUG, "Radar: max range " << maxrange);
     return maxrange >= range_nm;
 }