# include <config.h>
#endif
+#include <simgear/math/vector.hxx>
#include <Main/viewer.hxx>
#include "HUD.hxx"
_div_units(int(fabs(n->getFloatValue("divisions")))),
_scr_hole(n->getIntValue("screen-hole")),
_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")),
float roll_value = _roll.getFloatValue() * SGD_DEGREES_TO_RADIANS;
float pitch_value = _pitch.getFloatValue();
- float alpha;
-
- bool pitch_ladder;
- bool climb_dive_ladder;
- bool clip_plane;
-
- if (_type == CLIMB_DIVE) {
- pitch_ladder = false;
- climb_dive_ladder = true;
- clip_plane = true;
-
- } else { // _type == PITCH
- pitch_ladder = true;
- climb_dive_ladder = false;
- clip_plane = false;
- }
//**************************************************************
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();
//****************************************************************
// Clipping coordinates for ladder to be input from xml file
- // Clip hud ladder
- if (clip_plane) {
+ // 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};
glEnable(GL_CLIP_PLANE1);
glClipPlane(GL_CLIP_PLANE2, eqn_right);
glEnable(GL_CLIP_PLANE2);
- // glScissor(-100,-240, 200, 240);
- // glEnable(GL_SCISSOR_TEST);
}
//****************************************************************
} // if _velocity_vector
// draw hud markers on top of each AI/MP target
- if ( _target_markers ) {
- SGPropertyNode *models
- = globals->get_props()->getNode("/ai/models", true);
- for ( int i = 0; i < models->nChildren(); i++ ) {
+ if (_target_markers) {
+ SGPropertyNode *models = globals->get_props()->getNode("/ai/models", true);
+ for (int i = 0; i < models->nChildren(); i++) {
SGPropertyNode *chld = models->getChild(i);
string name;
name = chld->getName();
- if ( name == "aircraft" || name == "multiplayer" ) {
+ if (name == "aircraft" || name == "multiplayer") {
string callsign = chld->getStringValue("callsign");
- if ( callsign != "" ) {
+ if (callsign != "") {
float h_deg = chld->getFloatValue("radar/h-offset");
float v_deg = chld->getFloatValue("radar/v-offset");
float pos_x = (h_deg * cos(roll_value) -
//****************************************************************
- if (climb_dive_ladder) { // CONFORMAL_HUD
- _vmin = pitch_value - _width_units;
- _vmax = pitch_value + _width_units;
- glTranslatef(vel_x, vel_y, 0);
-
- } else { // pitch_ladder - Default Hud
+ if (_dynamic_origin) {
+ // ladder moves with alpha/beta offset projected onto horizon
+ // line (so that the horizon line always aligns with the
+ // actual horizon.
+ _vmin = pitch_value - _width_units * 0.5f;
+ _vmax = pitch_value + _width_units * 0.5f;
+ {
+ // the hud ladder center point should move relative to alpha/beta
+ // 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);
+ }
+ } else {
+ // ladder position is fixed relative to the center of the screen.
_vmin = pitch_value - _width_units * 0.5f;
_vmax = pitch_value + _width_units * 0.5f;
}
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;
+ float y = 0, y_end = 0;
float x_ini, x_ini2;
float x_end, x_end2;
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;
-
- if (climb_dive_ladder)
- zero_offset = 50.0f; // horizon line is wider by this much (hard coded ??)
- else
- zero_offset = 10.0f;
-
- fntFont *font = _hud->_font_renderer->getFont(); // FIXME
- float pointsize = _hud->_font_renderer->getPointSize();
- float italic = _hud->_font_renderer->getSlant();
+ const float zero_offset = 50.0f; // horizon line is wider by this much
_locTextList.setFont(_hud->_font_renderer);
_locTextList.erase();
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;
+ if (i == 0) {
+ draw_line(x_ini - zero_offset, y, x_end + zero_offset, y);
+ continue;
+ } else if (i > 0) {
// Zero or above draw solid lines
draw_line(x_ini, y, x_end, y);
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);
+ draw_text(x_ini - 4, y, buf, VCENTER|RIGHT);
+ draw_text(x_end + 4, y, buf, VCENTER|LEFT);
}
}
x_ini2 = half_span - hole;
for (; i < last; i++) {
- if (_type == PITCH)
+ if (_type == PITCH) {
y = float(i - pitch_value) * _compression + .5;
- else // _type == CLIMB_DIVE
+ } else { // _type == CLIMB_DIVE
y = float(i - actslope) * _compression + .5;
+ }
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;
+ y_end = y;
+
+ if (i == 0) {
+ // make zero point wider
+ x_ini -= zero_offset;
+ x_end2 += zero_offset;
+
+ draw_line(x_ini, y, x_end, y);
+ draw_line(x_ini2, y, x_end2, y);
+
+ draw_text(x_ini - 2.0, y, buf, VCENTER|RIGHT);
+ draw_text(x_end2 + 2.0, y, buf, VCENTER|LEFT);
+
+ } else if (i > 0) {
+ // draw climb bar vertical lines
+ draw_line(x_ini, y - 5.0, x_ini, y);
+ draw_line(x_end2, y - 5.0, x_end2, y);
- if (i >= 0) {
- // Make zero point wider on left
- if (i == 0) {
- x_ini -= zero_offset;
- x_end2 += zero_offset;
- }
- //draw climb bar vertical lines
- if (climb_dive_ladder) {
- // Zero or above draw solid 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);
+ draw_text(x_ini + 0.5, y - 0.5, buf, TOP|LEFT);
+ draw_text(x_end2 - 0.5, y - 0.5, buf, TOP|RIGHT);
+
if (i == 90 && _zenith)
draw_zenith(0.0, y);
} else { // i < 0
+ float alpha = i * SG_DEGREES_TO_RADIANS / 2.0;
+ y_end = y + (x_end - x_ini) * sin(alpha);
+
+ float w = (x_end - x_ini) * cos(alpha);
+ x_ini = x_end - w;
+ x_end2 = x_ini2 + w;
+
// draw dive bar vertical lines
- if (climb_dive_ladder) {
- draw_line(x_end, y + 5.0, x_end, y);
- draw_line(x_ini2, y + 5.0, x_ini2, y);
- }
+ 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, x_end, y);
- draw_stipple_line(x_ini2, y, x_end2, y);
+ draw_stipple_line(x_end, y, x_ini, y_end);
+ draw_stipple_line(x_ini2, y, x_end2, y_end);
+
+ float yoffs = 1.0 + (y - y_end) / 4.0; // too hackish?
+ draw_text(x_ini + 3.0, y_end + yoffs, buf, BOTTOM|HCENTER);
+ // right number shifted in a little more, because of the minus
+ draw_text(x_end2 - 4.0, y_end + yoffs, buf, BOTTOM|HCENTER);
if (i == -90 && _nadir)
draw_nadir(0.0, y);
}
-
- // Now calculate the location of the left side label using
- draw_text(x_ini - text_offset - label_length + 2.5/*hack*/, y - label_height, buf);
- draw_text(x_end2 + text_offset, y - label_height, buf);
}
}
glDisable(GL_CLIP_PLANE0);
glDisable(GL_CLIP_PLANE1);
glDisable(GL_CLIP_PLANE2);
- // glDisable(GL_SCISSOR_TEST);
glPopMatrix();
//*************************************************************