From aa8bccf93e5fc4ef11062583459df4e26c996d3f Mon Sep 17 00:00:00 2001
From: "Meazza@.(none)" <Meazza@.(none)>
Date: Fri, 5 Feb 2010 08:45:15 +0000
Subject: [PATCH 1/4] Add Tachymetric Gunsight

Signed-off-by:  <V Meazza>
---
 src/Instrumentation/HUD/HUD.hxx            | 17 ++++
 src/Instrumentation/HUD/HUD_instrument.cxx | 14 ++++
 src/Instrumentation/HUD/HUD_misc.cxx       | 95 +++++++++++++++++++---
 3 files changed, 116 insertions(+), 10 deletions(-)

diff --git a/src/Instrumentation/HUD/HUD.hxx b/src/Instrumentation/HUD/HUD.hxx
index fbf4baed3..6776495f2 100644
--- a/src/Instrumentation/HUD/HUD.hxx
+++ b/src/Instrumentation/HUD/HUD.hxx
@@ -357,6 +357,7 @@ protected:
     void draw_stipple_line(float x1, float y1, float x2, float y2);
     void draw_text(float x, float y, const char *msg, int align = 0, int digit = 0);
     void draw_circle(float x1, float y1, float r) const;
+    void draw_arc(float x1, float y1, float t0, float t1, float r) const;
     void draw_bullet(float, float, float);
 
     HUD         *_hud;
@@ -610,9 +611,25 @@ public:
 
 private:
     SGSharedPtr<SGCondition> _active_condition;  // stadiametric (true) or standby (false)
+    SGSharedPtr<SGCondition> _tachy_condition;  // tachymetric (true) or standby (false)
+    SGSharedPtr<SGCondition> _align_condition;  // tachymetric (true) or standby (false)
+
     Input   _diameter;               // inner/outer radius relation
+    Input  _pitch;
+    Input  _yaw;
+    Input  _speed;
+    Input  _range;
+    Input  _t0;
+    Input  _t1;
+    Input  _offset_x;
+    Input  _offset_y;
+
     float   _bullet_size;
     float   _inner_radius;
+    float   _compression;
+    float  _limit_x;
+    float  _limit_y;
+
 };
 
 
diff --git a/src/Instrumentation/HUD/HUD_instrument.cxx b/src/Instrumentation/HUD/HUD_instrument.cxx
index a6769c609..630837581 100644
--- a/src/Instrumentation/HUD/HUD_instrument.cxx
+++ b/src/Instrumentation/HUD/HUD_instrument.cxx
@@ -118,6 +118,20 @@ void HUD::Item::draw_circle(float xoffs, float yoffs, float r) const
     glEnd();
 }
 
+void HUD::Item::draw_arc(float xoffs, float yoffs, float t0, float t1, float r) const
+{
+    glBegin(GL_LINE_STRIP);
+    float step = SG_PI / r;
+    t0 = t0 * SG_DEGREES_TO_RADIANS;
+    t1 = t1 * SG_DEGREES_TO_RADIANS;
+
+    for (float alpha = t0; alpha < t1; alpha += step) {
+        float x = r * cos(alpha);
+        float y = r * sin(alpha);
+        glVertex2f(x + xoffs, y + yoffs);
+    }
+    glEnd();
+}
 
 void HUD::Item::draw_bullet(float x, float y, float size)
 {
diff --git a/src/Instrumentation/HUD/HUD_misc.cxx b/src/Instrumentation/HUD/HUD_misc.cxx
index 021e22ba2..2ee8a9010 100644
--- a/src/Instrumentation/HUD/HUD_misc.cxx
+++ b/src/Instrumentation/HUD/HUD_misc.cxx
@@ -24,38 +24,113 @@
 
 #include "HUD.hxx"
 
-
 // MIL-STD-1787B aiming reticle
 
 HUD::AimingReticle::AimingReticle(HUD *hud, const SGPropertyNode *n, float x, float y) :
-    Item(hud, n, x, y),
-    _active_condition(0),
-    _diameter(n->getNode("diameter-input", false)),
-    _bullet_size(_w / 6.0),
-    _inner_radius(_w / 2.0)
+Item(hud, n, x, y),
+_pitch(n->getNode("pitch-input", false)),
+_yaw(n->getNode("yaw-input", false)),
+_speed(n->getNode("speed-input", false)),
+_range(n->getNode("range-input", false)),
+_offset_x(n->getNode("offset-x-input", false)),
+_offset_y(n->getNode("offset-y-input", false)),
+_diameter(n->getNode("diameter-input", false)),
+_t0(n->getNode("arc-start-input", false)),
+_t1(n->getNode("arc-stop-input", false)),
+_compression(n->getFloatValue("compression-factor")),
+_limit_x(n->getFloatValue("limit-x")),
+_limit_y(n->getFloatValue("limit-y")),
+_active_condition(0),
+_tachy_condition(0),
+_align_condition(0),
+_bullet_size(_w / 6.0),
+_inner_radius(_w / 2.0)
+
 {
     const SGPropertyNode *node = n->getNode("active-condition");
     if (node)
-       _active_condition = sgReadCondition(globals->get_props(), node);
+        _active_condition = sgReadCondition(globals->get_props(), node);
+
+    const SGPropertyNode *tnode = n->getNode("tachy-condition");
+    if (tnode)
+        _tachy_condition = sgReadCondition(globals->get_props(), tnode);
+    
+    const SGPropertyNode *anode = n->getNode("align-condition");
+    if (anode)
+        _align_condition = sgReadCondition(globals->get_props(), anode);
 }
 
 
 void HUD::AimingReticle::draw(void)
 {
     bool active = _active_condition ? _active_condition->test() : true;
-    float diameter = _diameter.isValid() ? _diameter.getFloatValue() : 2.0f; // outer circle
+    bool tachy = _tachy_condition ? _tachy_condition->test() : true;
+    bool align = _align_condition ? _align_condition->test() : true;
 
-    float x = _center_x;
-    float y = _center_y;
+    float diameter = _diameter.isValid() ? _diameter.getFloatValue() : 2.0f; // outer circle
+    float x = _center_x + _offset_x.getFloatValue();
+    float y = _center_y + _offset_y.getFloatValue();
+
+    float t0 = _t0.isValid() ? _t0.getFloatValue() : 2.0f; // start arc
+    float t1 = _t1.isValid() ? _t1.getFloatValue() : 2.0f; // start arc
+
+    float yaw_value = _yaw.getFloatValue();
+    float pitch_value = _pitch.getFloatValue();
+    float tof_value = _range.getFloatValue()* 3 / _speed.getFloatValue();
+
+//        SG_LOG(SG_INPUT, SG_ALERT, "HUD: compression" << _compression);
+
+//        SG_LOG(SG_INPUT, SG_ALERT, "HUD: limit_x" << _limit_x);
 
     if (active) { // stadiametric (4.2.4.4)
         draw_bullet(x, y, _bullet_size);
         draw_circle(x, y, _inner_radius);
         draw_circle(x, y, diameter * _inner_radius);
+    } else if (tachy){//tachiametric
+        draw_bullet(x, y, _bullet_size);
+        draw_circle(x, y, _inner_radius);
+        draw_line(x + _inner_radius, y, x + _inner_radius * 3, y);
+        draw_line(x - _inner_radius, y, x - _inner_radius * 3, y);
+        draw_line(x, y + _inner_radius, x, y + _inner_radius * 3);
+        draw_line(x, y - _inner_radius, x, y - _inner_radius * 3);
+
+        if(align){
+            draw_line(x + _limit_x, y + _limit_y, x - _limit_x, y + _limit_y);
+            draw_line(x + _limit_x, y - _limit_y, x - _limit_x, y - _limit_y);
+            draw_line(x + _limit_x, y + _limit_y, x + _limit_x, y - _limit_y);
+            draw_line(x - _limit_x, y + _limit_y, x - _limit_x, y - _limit_y);
+        }
+
+        float limit_offset = diameter * _inner_radius;
+
+        float pos_x = x + (yaw_value * tof_value)
+            * _compression;
+
+        pos_x > x + _limit_x - limit_offset ? 
+            pos_x = x + _limit_x - limit_offset : pos_x;
+
+        pos_x < x - _limit_x + limit_offset ? 
+            pos_x = x - _limit_x + limit_offset: pos_x;
+
+        float pos_y = y + (pitch_value * tof_value)
+            * _compression;
+
+        pos_y > y + _limit_y - limit_offset ? 
+            pos_y = y + _limit_y - limit_offset : pos_y;
+
+        pos_y < y - _limit_y + limit_offset? 
+            pos_y = y - _limit_y + limit_offset: pos_y;
+
+        //        SG_LOG(SG_INPUT, SG_ALERT, "HUD: pos y" << pos_y);
+
+        draw_circle(pos_x, pos_y, diameter * _inner_radius);
+
+        draw_arc(x, y, t0, t1, (diameter + 2) * _inner_radius );
 
     } else { // standby (4.2.4.5)
         // TODO
     }
+
 }
 
 

From 4027a92f882f154fe826c332bf2f61309acce72a Mon Sep 17 00:00:00 2001
From: Tim Moore <timoore33@gmail.com>
Date: Thu, 11 Feb 2010 00:13:04 +0100
Subject: [PATCH 2/4] Only draw tachymetric sight if appropriate inputs exist

This avoids triggering asserts for missing inputs.
---
 src/Instrumentation/HUD/HUD.hxx      |  1 +
 src/Instrumentation/HUD/HUD_misc.cxx | 28 ++++++++++++++++------------
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/src/Instrumentation/HUD/HUD.hxx b/src/Instrumentation/HUD/HUD.hxx
index 6776495f2..50b81da68 100644
--- a/src/Instrumentation/HUD/HUD.hxx
+++ b/src/Instrumentation/HUD/HUD.hxx
@@ -623,6 +623,7 @@ private:
     Input  _t1;
     Input  _offset_x;
     Input  _offset_y;
+    bool _hasTachyInputs;
 
     float   _bullet_size;
     float   _inner_radius;
diff --git a/src/Instrumentation/HUD/HUD_misc.cxx b/src/Instrumentation/HUD/HUD_misc.cxx
index 2ee8a9010..a9090bf79 100644
--- a/src/Instrumentation/HUD/HUD_misc.cxx
+++ b/src/Instrumentation/HUD/HUD_misc.cxx
@@ -28,15 +28,16 @@
 
 HUD::AimingReticle::AimingReticle(HUD *hud, const SGPropertyNode *n, float x, float y) :
 Item(hud, n, x, y),
+_diameter(n->getNode("diameter-input", false)),
 _pitch(n->getNode("pitch-input", false)),
 _yaw(n->getNode("yaw-input", false)),
 _speed(n->getNode("speed-input", false)),
 _range(n->getNode("range-input", false)),
-_offset_x(n->getNode("offset-x-input", false)),
-_offset_y(n->getNode("offset-y-input", false)),
-_diameter(n->getNode("diameter-input", false)),
 _t0(n->getNode("arc-start-input", false)),
 _t1(n->getNode("arc-stop-input", false)),
+_offset_x(n->getNode("offset-x-input", false)),
+_offset_y(n->getNode("offset-y-input", false)),
+_hasTachyInputs(false),
 _compression(n->getFloatValue("compression-factor")),
 _limit_x(n->getFloatValue("limit-x")),
 _limit_y(n->getFloatValue("limit-y")),
@@ -58,6 +59,9 @@ _inner_radius(_w / 2.0)
     const SGPropertyNode *anode = n->getNode("align-condition");
     if (anode)
         _align_condition = sgReadCondition(globals->get_props(), anode);
+    _hasTachyInputs = _pitch.isValid() && _yaw.isValid() && _speed.isValid()
+        && _range.isValid() && _t0.isValid() && _t1.isValid()
+        && _offset_x.isValid() && _offset_y.isValid();
 }
 
 
@@ -68,15 +72,9 @@ void HUD::AimingReticle::draw(void)
     bool align = _align_condition ? _align_condition->test() : true;
 
     float diameter = _diameter.isValid() ? _diameter.getFloatValue() : 2.0f; // outer circle
-    float x = _center_x + _offset_x.getFloatValue();
-    float y = _center_y + _offset_y.getFloatValue();
+    float x = _center_x + (_offset_x.isValid() ? _offset_x.getFloatValue() : 0);
+    float y = _center_y + (_offset_y.isValid() ? _offset_y.getFloatValue() : 0);
 
-    float t0 = _t0.isValid() ? _t0.getFloatValue() : 2.0f; // start arc
-    float t1 = _t1.isValid() ? _t1.getFloatValue() : 2.0f; // start arc
-
-    float yaw_value = _yaw.getFloatValue();
-    float pitch_value = _pitch.getFloatValue();
-    float tof_value = _range.getFloatValue()* 3 / _speed.getFloatValue();
 
 //        SG_LOG(SG_INPUT, SG_ALERT, "HUD: compression" << _compression);
 
@@ -86,7 +84,13 @@ void HUD::AimingReticle::draw(void)
         draw_bullet(x, y, _bullet_size);
         draw_circle(x, y, _inner_radius);
         draw_circle(x, y, diameter * _inner_radius);
-    } else if (tachy){//tachiametric
+    } else if (tachy && _hasTachyInputs){//tachiametric
+        float t0 = _t0.isValid() ? _t0.getFloatValue() : 2.0f; // start arc
+        float t1 = _t1.isValid() ? _t1.getFloatValue() : 2.0f; // start arc
+        float yaw_value = _yaw.getFloatValue();
+        float pitch_value = _pitch.getFloatValue();
+        float tof_value = _range.getFloatValue()* 3 / _speed.getFloatValue();
+        
         draw_bullet(x, y, _bullet_size);
         draw_circle(x, y, _inner_radius);
         draw_line(x + _inner_radius, y, x + _inner_radius * 3, y);

From f112fc46389499c107546295b7dbcaa823f0d03e Mon Sep 17 00:00:00 2001
From: V Meazza <vivina.meazza@lineone.net>
Date: Fri, 19 Feb 2010 23:45:19 +0000
Subject: [PATCH 3/4] Revised bugfix for tachymetric gunsight

---
 src/Instrumentation/HUD/HUD.hxx      |  1 -
 src/Instrumentation/HUD/HUD_misc.cxx | 23 ++++++-----------------
 2 files changed, 6 insertions(+), 18 deletions(-)

diff --git a/src/Instrumentation/HUD/HUD.hxx b/src/Instrumentation/HUD/HUD.hxx
index 50b81da68..6776495f2 100644
--- a/src/Instrumentation/HUD/HUD.hxx
+++ b/src/Instrumentation/HUD/HUD.hxx
@@ -623,7 +623,6 @@ private:
     Input  _t1;
     Input  _offset_x;
     Input  _offset_y;
-    bool _hasTachyInputs;
 
     float   _bullet_size;
     float   _inner_radius;
diff --git a/src/Instrumentation/HUD/HUD_misc.cxx b/src/Instrumentation/HUD/HUD_misc.cxx
index a9090bf79..7b084c68b 100644
--- a/src/Instrumentation/HUD/HUD_misc.cxx
+++ b/src/Instrumentation/HUD/HUD_misc.cxx
@@ -37,7 +37,6 @@ _t0(n->getNode("arc-start-input", false)),
 _t1(n->getNode("arc-stop-input", false)),
 _offset_x(n->getNode("offset-x-input", false)),
 _offset_y(n->getNode("offset-y-input", false)),
-_hasTachyInputs(false),
 _compression(n->getFloatValue("compression-factor")),
 _limit_x(n->getFloatValue("limit-x")),
 _limit_y(n->getFloatValue("limit-y")),
@@ -55,42 +54,34 @@ _inner_radius(_w / 2.0)
     const SGPropertyNode *tnode = n->getNode("tachy-condition");
     if (tnode)
         _tachy_condition = sgReadCondition(globals->get_props(), tnode);
-    
+
     const SGPropertyNode *anode = n->getNode("align-condition");
     if (anode)
         _align_condition = sgReadCondition(globals->get_props(), anode);
-    _hasTachyInputs = _pitch.isValid() && _yaw.isValid() && _speed.isValid()
-        && _range.isValid() && _t0.isValid() && _t1.isValid()
-        && _offset_x.isValid() && _offset_y.isValid();
+
 }
 
 
 void HUD::AimingReticle::draw(void)
 {
     bool active = _active_condition ? _active_condition->test() : true;
-    bool tachy = _tachy_condition ? _tachy_condition->test() : true;
-    bool align = _align_condition ? _align_condition->test() : true;
+    bool tachy = _tachy_condition ? _tachy_condition->test() : false;
+    bool align = _align_condition ? _align_condition->test() : false;
 
     float diameter = _diameter.isValid() ? _diameter.getFloatValue() : 2.0f; // outer circle
     float x = _center_x + (_offset_x.isValid() ? _offset_x.getFloatValue() : 0);
     float y = _center_y + (_offset_y.isValid() ? _offset_y.getFloatValue() : 0);
 
-
-//        SG_LOG(SG_INPUT, SG_ALERT, "HUD: compression" << _compression);
-
-//        SG_LOG(SG_INPUT, SG_ALERT, "HUD: limit_x" << _limit_x);
-
     if (active) { // stadiametric (4.2.4.4)
         draw_bullet(x, y, _bullet_size);
         draw_circle(x, y, _inner_radius);
         draw_circle(x, y, diameter * _inner_radius);
-    } else if (tachy && _hasTachyInputs){//tachiametric
+    } else if (tachy){//tachiametric
         float t0 = _t0.isValid() ? _t0.getFloatValue() : 2.0f; // start arc
-        float t1 = _t1.isValid() ? _t1.getFloatValue() : 2.0f; // start arc
+        float t1 = _t1.isValid() ? _t1.getFloatValue() : 2.0f; // stop arc
         float yaw_value = _yaw.getFloatValue();
         float pitch_value = _pitch.getFloatValue();
         float tof_value = _range.getFloatValue()* 3 / _speed.getFloatValue();
-        
         draw_bullet(x, y, _bullet_size);
         draw_circle(x, y, _inner_radius);
         draw_line(x + _inner_radius, y, x + _inner_radius * 3, y);
@@ -125,8 +116,6 @@ void HUD::AimingReticle::draw(void)
         pos_y < y - _limit_y + limit_offset? 
             pos_y = y - _limit_y + limit_offset: pos_y;
 
-        //        SG_LOG(SG_INPUT, SG_ALERT, "HUD: pos y" << pos_y);
-
         draw_circle(pos_x, pos_y, diameter * _inner_radius);
 
         draw_arc(x, y, t0, t1, (diameter + 2) * _inner_radius );

From cb81aa9f65d5eb4bb7bd9d8e68ce4f4c38bdc491 Mon Sep 17 00:00:00 2001
From: torsten <torsten>
Date: Sat, 6 Mar 2010 21:20:21 +0000
Subject: [PATCH 4/4] one more gcc warning fix: xxx will be initialized after
 yyy

---
 src/Instrumentation/HUD/HUD_misc.cxx | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/Instrumentation/HUD/HUD_misc.cxx b/src/Instrumentation/HUD/HUD_misc.cxx
index 7b084c68b..891101713 100644
--- a/src/Instrumentation/HUD/HUD_misc.cxx
+++ b/src/Instrumentation/HUD/HUD_misc.cxx
@@ -28,6 +28,9 @@
 
 HUD::AimingReticle::AimingReticle(HUD *hud, const SGPropertyNode *n, float x, float y) :
 Item(hud, n, x, y),
+_active_condition(0),
+_tachy_condition(0),
+_align_condition(0),
 _diameter(n->getNode("diameter-input", false)),
 _pitch(n->getNode("pitch-input", false)),
 _yaw(n->getNode("yaw-input", false)),
@@ -37,14 +40,11 @@ _t0(n->getNode("arc-start-input", false)),
 _t1(n->getNode("arc-stop-input", false)),
 _offset_x(n->getNode("offset-x-input", false)),
 _offset_y(n->getNode("offset-y-input", false)),
+_bullet_size(_w / 6.0),
+_inner_radius(_w / 2.0),
 _compression(n->getFloatValue("compression-factor")),
 _limit_x(n->getFloatValue("limit-x")),
-_limit_y(n->getFloatValue("limit-y")),
-_active_condition(0),
-_tachy_condition(0),
-_align_condition(0),
-_bullet_size(_w / 6.0),
-_inner_radius(_w / 2.0)
+_limit_y(n->getFloatValue("limit-y"))
 
 {
     const SGPropertyNode *node = n->getNode("active-condition");