# include <config.h>
#endif
-#include <simgear/math/vector.hxx>
+#include <sstream>
+#include <simgear/math/SGGeometry.hxx>
#include <Main/viewer.hxx>
#include "HUD.hxx"
-
// FIXME
-float get__heading() { return fgGetFloat("/orientation/heading-deg") * M_PI / 180.0; }
-float get__throttleval() { return fgGetFloat("/controls/engines/engine/throttle"); }
-float get__Vx() { return fgGetFloat("/velocities/uBody-fps"); }
-float get__Vy() { return fgGetFloat("/velocities/vBody-fps"); }
-float get__Vz() { return fgGetFloat("/velocities/wBody-fps"); }
-float get__Ax() { return fgGetFloat("/acclerations/pilot/x-accel-fps_sec"); }
-float get__Ay() { return fgGetFloat("/acclerations/pilot/y-accel-fps_sec"); }
-float get__Az() { return fgGetFloat("/acclerations/pilot/z-accel-fps_sec"); }
-float get__alpha() { return fgGetFloat("/orientation/alpha-deg"); }
-float get__beta() { return fgGetFloat("/orientation/side-slip-deg"); }
+static float get__heading() { return fgGetFloat("/orientation/heading-deg") * M_PI / 180.0; }
+static float get__throttleval() { return fgGetFloat("/controls/engines/engine/throttle"); }
+static float get__Vx() { return fgGetFloat("/velocities/uBody-fps"); }
+static float get__Vy() { return fgGetFloat("/velocities/vBody-fps"); }
+static float get__Vz() { return fgGetFloat("/velocities/wBody-fps"); }
+static float get__Ax() { return fgGetFloat("/accelerations/pilot/x-accel-fps_sec"); }
+static float get__Ay() { return fgGetFloat("/accelerations/pilot/y-accel-fps_sec"); }
+static float get__Az() { return fgGetFloat("/accelerations/pilot/z-accel-fps_sec"); }
+static float get__alpha() { return fgGetFloat("/orientation/alpha-deg"); }
+static float get__beta() { return fgGetFloat("/orientation/side-slip-deg"); }
#undef ENABLE_SP_FDM
_roll(n->getNode("roll-input", false)),
_width_units(int(n->getFloatValue("display-span"))),
_div_units(int(fabs(n->getFloatValue("divisions")))),
- _scr_hole(n->getIntValue("screen-hole")),
+ _scr_hole(fabsf(n->getFloatValue("screen-hole")) * 0.5f),
+ _zero_bar_overlength(n->getFloatValue("zero-bar-overlength", 10)),
+ _dive_bar_angle(n->getBoolValue("enable-dive-bar-angle")),
+ _tick_length(n->getFloatValue("tick-length")),
_compression(n->getFloatValue("compression-factor")),
_dynamic_origin(n->getBoolValue("enable-dynamic-origin")),
- _clip_plane(n->getBoolValue("enable-clip-plane")),
_frl(n->getBoolValue("enable-fuselage-ref-line")),
_target_spot(n->getBoolValue("enable-target-spot")),
_target_markers(n->getBoolValue("enable-target-markers")),
_waypoint_marker(n->getBoolValue("enable-waypoint-marker")),
_zenith(n->getBoolValue("enable-zenith")),
_nadir(n->getBoolValue("enable-nadir")),
- _hat(n->getBoolValue("enable-hat"))
+ _hat(n->getBoolValue("enable-hat")),
+ _clip_box(new ClipBox(n->getNode("clipping")))
{
const char *t = n->getStringValue("type");
_type = strcmp(t, "climb-dive") ? PITCH : CLIMB_DIVE;
}
+HUD::Ladder::~Ladder()
+{
+ delete _clip_box;
+}
+
void HUD::Ladder::draw(void)
{
if (!_pitch.isValid() || !_roll.isValid())
float roll_value = _roll.getFloatValue() * SGD_DEGREES_TO_RADIANS;
float pitch_value = _pitch.getFloatValue();
- float alpha;
//**************************************************************
glPushMatrix();
float Axx = 0.0, Ayy = 0.0, Azz = 0.0, total_vel = 0.0, pot_slope, t1;
float up_vel, ground_vel, actslope = 0.0, psi = 0.0;
float vel_x = 0.0, vel_y = 0.0, drift;
+ float alpha;
if (_velocity_vector) {
drift = get__beta();
glEnd();
}
- //****************************************************************
- // Clipping coordinates for ladder to be input from xml file
- // Clip hud ladder. FIXME, these should be configurable, but they
- // have always been hardcoded here.
- if (_clip_plane) {
- GLdouble eqn_top[4] = {0.0, -1.0, 0.0, 0.0};
- GLdouble eqn_left[4] = {-1.0, 0.0, 0.0, 100.0};
- GLdouble eqn_right[4] = {1.0, 0.0, 0.0, 100.0};
-
- glClipPlane(GL_CLIP_PLANE0, eqn_top);
- glEnable(GL_CLIP_PLANE0);
- glClipPlane(GL_CLIP_PLANE1, eqn_left);
- glEnable(GL_CLIP_PLANE1);
- glClipPlane(GL_CLIP_PLANE2, eqn_right);
- glEnable(GL_CLIP_PLANE2);
- }
-
//****************************************************************
// OBJECT MOVING RETICLE
// TYPE VELOCITY VECTOR
//****************************************************************
+ _clip_box->set();
+
if (_dynamic_origin) {
// ladder moves with alpha/beta offset projected onto horizon
// line (so that the horizon line always aligns with the
// however the horizon line should always stay on the horizon. We
// project the alpha/beta offset onto the horizon line to get the
// result we want.
- sgdVec3 p1; // result
- sgdVec3 p; sgdSetVec3(p, vel_x, vel_y, 0.0);
- sgdVec3 p0; sgdSetVec3(p0, 0.0, 0.0, 0.0);
- sgdVec3 d; sgdSetVec3(d, cos(roll_value), sin(roll_value), 0.0);
- sgdClosestPointToLine( p1, p, p0, d );
- glTranslatef(p1[0], p1[1], 0);
+
+ SGVec3d d(cos(roll_value), sin(roll_value), 0.0);
+ SGRayd r(SGVec3d::zeros(), d);
+ SGVec3d p = r.getClosestPointTo(SGVec3d(vel_x, vel_y, 0.0));
+ glTranslatef(p[0], p[1], 0);
}
} else {
// ladder position is fixed relative to the center of the screen.
}
glRotatef(roll_value * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0);
+
// FRL marker not rotated - this line shifted below
- float half_span = _w / 2.0;
- float y = 0, y_end = 0;
- float x_ini, x_ini2;
- float x_end, x_end2;
+ float half_span = _w * 0.5f;
+ float y = 0;
+ struct { float x, y; } lo, li, ri, ro, numoffs; // left/right inner/outer
if (_div_units) {
- const int BUFSIZE = 8;
- char buf[BUFSIZE];
- float label_length;
- float label_height;
- float left;
- float right;
- float bot;
- float top;
- float text_offset = 4.0f;
- float zero_offset = 0.0;
-
- // horizon line is wider by this much (hard coded ??)
- zero_offset = 50.0f;
-
- fntFont *font = _hud->_font_renderer->getFont(); // FIXME
- float pointsize = _hud->_font_renderer->getPointSize();
- float italic = _hud->_font_renderer->getSlant();
-
_locTextList.setFont(_hud->_font_renderer);
_locTextList.erase();
_locLineList.erase();
_locStippleLineList.erase();
- int last = int(_vmax) + 1;
- int i = int(_vmin);
-
- if (!_scr_hole) {
- x_end = half_span;
-
- for (; i < last; i++) {
- y = (i - pitch_value) * _compression + .5f;
-
- if (!(i % _div_units)) { // At integral multiple of div
- snprintf(buf, BUFSIZE, "%d", i);
- font->getBBox(buf, pointsize, italic, &left, &right, &bot, &top);
- label_length = right + left;
- label_height = (top + bot) / 2.0f;
-
- x_ini = -half_span;
-
- if (i >= 0) {
- // Make zero point wider on left
- if (i == 0)
- x_ini -= zero_offset;
-
- // Zero or above draw solid lines
- draw_line(x_ini, y, x_end, y);
-
- if (i == 90 && _zenith)
- draw_zenith(0.0, y);
- } else {
- // Below zero draw dashed lines.
- draw_stipple_line(x_ini, y, x_end, y);
-
- if (i == -90 && _nadir)
- draw_nadir(0.0, y);
- }
-
- // Calculate the position of the left text and write it.
- draw_text(x_ini - text_offset - label_length + 2.5/*hack*/, y - label_height, buf);
- draw_text(x_end + text_offset, y - label_height, buf);
- }
- }
-
- } else { // if (_scr_hole)
- // Draw ladder with space in the middle of the lines
- float hole = _scr_hole / 2.0f;
-
- x_end = -half_span + hole;
- x_ini2 = half_span - hole;
-
- for (; i < last; i++) {
- if (_type == PITCH) {
- y = float(i - pitch_value) * _compression + .5;
- } else {
- // _type == CLIMB_DIVE
- y = float(i - actslope) * _compression + .5;
- }
- if ( i < 0 )
- y_end = y +
- sin(0.5 * i * SG_DEGREES_TO_RADIANS * 3/*hack*/) *
- _compression;
- else
- y_end = y;
-
- if (!(i % _div_units)) { // At integral multiple of div
- snprintf(buf, BUFSIZE, "%d", i);
- font->getBBox(buf, pointsize, italic, &left, &right, &bot, &top);
- label_length = right + left;
- label_height = (top + bot) / 2.0f;
- //printf("%s -- l %f r %f b %f t %f\n", buf, left, right, bot, top);
-
- // Start by calculating the points and drawing the
- // left side lines.
- x_ini = -half_span;
- x_end2 = half_span;
-
- if (i >= 0) {
- // Make zero point wider on left
- if (i == 0) {
- x_ini -= zero_offset;
- x_end2 += zero_offset;
- } else {
- //draw climb bar vertical lines
- draw_line(x_end, y - 5.0, x_end, y);
- draw_line(x_ini2, y - 5.0, x_ini2, y);
- }
- // draw pitch / climb bar
- draw_line(x_ini, y, x_end, y);
- draw_line(x_ini2, y, x_end2, y);
-
- if (i == 90 && _zenith)
- draw_zenith(0.0, y);
-
- } else { // i < 0
- // draw dive bar vertical lines
- draw_line(x_end, y + 5.0, x_end, y);
- draw_line(x_ini2, y + 5.0, x_ini2, y);
-
- // draw pitch / dive bars
- draw_stipple_line(x_ini, y_end, x_end, y);
- draw_stipple_line(x_ini2, y, x_end2, y_end);
-
- if (i == -90 && _nadir)
- draw_nadir(0.0, y);
- }
+ for (int i = int(_vmin); i < int(_vmax) + 1; i++) {
+ if (i % _div_units)
+ continue;
- // Now calculate the location of the left side label using
- draw_text(x_ini - text_offset - label_length + 2.5/*hack*/, y_end - label_height, buf);
- draw_text(x_end2 + text_offset, y_end - label_height, buf);
- }
- }
+ if (_type == PITCH)
+ y = float(i - pitch_value) * _compression + .5;
+ else // _type == CLIMB_DIVE
+ y = float(i - actslope) * _compression + .5;
// OBJECT LADDER MARK
// TYPE LINE
// ATTRIB - ON CONDITION
- // draw appraoch glide slope marker
+ // draw approach glide slope marker
#ifdef ENABLE_SP_FDM
if (_glide_slope_marker && ihook) {
draw_line(-half_span + 15, (_glide_slope - actslope) * _compression,
half_span - hole, (_glide_slope - actslope) * _compression);
}
#endif
+
+ // draw symbols
+ if (i == 90 && _zenith)
+ draw_zenith(0.0, y);
+ else if (i == -90 && _nadir)
+ draw_nadir(0.0, y);
+
+ if ((_zenith && i > 85) || i > 90)
+ continue;
+ if ((_nadir && i < -85) || i < -90)
+ continue;
+
+ lo.x = -half_span;
+ ro.x = half_span;
+ li.x = ri.x = 0;
+ lo.y = ro.y = li.y = ri.y = y;
+ numoffs.x = 4;
+ numoffs.y = 0;
+
+ if (i == 0) {
+ lo.x -= _zero_bar_overlength;
+ ro.x += _zero_bar_overlength;
+ }
+
+ if (_scr_hole > 0.0f) {
+ li.x = -_scr_hole;
+ ri.x = _scr_hole;
+
+ if (_dive_bar_angle && i < 0) {
+ float alpha = i * SG_DEGREES_TO_RADIANS * 0.5;
+ float xoffs = (ro.x - ri.x) * cos(alpha);
+ float yoffs = (ro.x - ri.x) * sin(alpha);
+ lo.x = li.x - xoffs;
+ ro.x = ri.x + xoffs;
+ lo.y = ro.y = li.y + yoffs;
+ numoffs.x = 0;
+ numoffs.y = 4 - yoffs * 0.3;
+ }
+ }
+
+ // draw bars
+ if (_scr_hole) {
+ draw_line(li.x, li.y, lo.x, lo.y, i < 0);
+ draw_line(ri.x, ri.y, ro.x, ro.y, i < 0);
+ } else {
+ draw_line(lo.x, lo.y, ro.x, ro.y, i < 0);
+ }
+
+ // draw ticks
+ if (_tick_length) {
+ if (i < 0) {
+ draw_line(li.x, li.y, li.x, li.y + _tick_length);
+ draw_line(ri.x, ri.y, ri.x, ri.y + _tick_length);
+ } else if (i > 0 || _zero_bar_overlength == 0) {
+ if (_tick_length > 0) {
+ numoffs.x = -0.3;
+ numoffs.y = -0.3;
+ draw_line(lo.x, lo.y, lo.x, lo.y - _tick_length);
+ draw_line(ro.x, ro.y, ro.x, ro.y - _tick_length);
+ } else {
+ draw_line(li.x, li.y, li.x, li.y - _tick_length);
+ draw_line(ri.x, ri.y, ri.x, ri.y - _tick_length);
+ }
+ }
+ }
+
+ // draw numbers
+ std::ostringstream str;
+ str << i;
+ // must keep this string, otherwise it will free the c_str!
+ string num_str = str.str();
+ const char *num = num_str.c_str();
+ int valign = numoffs.y > 0 ? BOTTOM : numoffs.y < 0 ? TOP : VCENTER;
+ draw_text(lo.x - numoffs.x, lo.y + numoffs.y, num,
+ valign | (numoffs.x == 0 ? CENTER : numoffs.x > 0 ? RIGHT : LEFT));
+ draw_text(ro.x + numoffs.x, lo.y + numoffs.y, num,
+ valign | (numoffs.x == 0 ? CENTER : numoffs.x > 0 ? LEFT : RIGHT));
+
}
_locTextList.draw();
_locStippleLineList.draw();
glDisable(GL_LINE_STIPPLE);
}
- glDisable(GL_CLIP_PLANE0);
- glDisable(GL_CLIP_PLANE1);
- glDisable(GL_CLIP_PLANE2);
+ _clip_box->unset();
glPopMatrix();
//*************************************************************