2006-07-04 15:32:55 +00:00
|
|
|
// HUD.hxx -- Head Up Display
|
|
|
|
//
|
|
|
|
// Written by Michele America, started September 1997.
|
|
|
|
//
|
|
|
|
// Copyright (C) 1997 Michele F. America [micheleamerica#geocities:com]
|
|
|
|
// Copyright (C) 2006 Melchior FRANZ [mfranz#aon:at]
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License as
|
|
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful, but
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
#ifndef _HUD_HXX
|
|
|
|
#define _HUD_HXX
|
|
|
|
|
|
|
|
#include <simgear/compiler.h>
|
2008-01-24 23:05:58 +00:00
|
|
|
#include <simgear/props/condition.hxx>
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <deque>
|
2008-07-25 18:38:29 +00:00
|
|
|
#include <fstream>
|
2006-07-04 15:32:55 +00:00
|
|
|
|
2008-07-27 16:25:13 +00:00
|
|
|
using std::deque;
|
|
|
|
using std::vector;
|
2006-07-04 15:32:55 +00:00
|
|
|
|
2006-10-29 19:30:21 +00:00
|
|
|
#include <osg/State>
|
|
|
|
|
2006-07-04 15:32:55 +00:00
|
|
|
#include <simgear/math/SGLimits.hxx>
|
|
|
|
#include <simgear/constants.h>
|
|
|
|
#include <simgear/structure/subsystem_mgr.hxx>
|
|
|
|
|
|
|
|
#include <Airports/runways.hxx> // FGRunway
|
|
|
|
#include <GUI/gui.h> // fntRenderer ? guiErrorMessage()
|
|
|
|
#include <GUI/new_gui.hxx> // FGFontCache, FGColor
|
|
|
|
#include <Main/fg_props.hxx>
|
|
|
|
|
|
|
|
|
|
|
|
class FGViewer;
|
|
|
|
|
|
|
|
|
2008-07-29 15:41:25 +00:00
|
|
|
class ClipBox {
|
|
|
|
public:
|
|
|
|
ClipBox(const SGPropertyNode *, float xoffset = 0, float yoffset = 0);
|
|
|
|
void set();
|
2008-07-30 14:52:01 +00:00
|
|
|
void unset();
|
2008-07-29 15:41:25 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
bool _active;
|
|
|
|
float _xoffs, _yoffs;
|
|
|
|
SGConstPropertyNode_ptr _top_node;
|
|
|
|
SGConstPropertyNode_ptr _bot_node;
|
|
|
|
SGConstPropertyNode_ptr _left_node;
|
|
|
|
SGConstPropertyNode_ptr _right_node;
|
|
|
|
GLdouble _top[4];
|
|
|
|
GLdouble _bot[4];
|
|
|
|
GLdouble _left[4];
|
|
|
|
GLdouble _right[4];
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-07-04 15:32:55 +00:00
|
|
|
class LineSegment {
|
|
|
|
public:
|
|
|
|
LineSegment(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1)
|
|
|
|
: _x0(x0), _y0(y0), _x1(x1), _y1(y1) {}
|
|
|
|
|
|
|
|
void draw() const {
|
|
|
|
glVertex2f(_x0, _y0);
|
|
|
|
glVertex2f(_x1, _y1);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
GLfloat _x0, _y0, _x1, _y1;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LineList {
|
|
|
|
public:
|
|
|
|
void add(const LineSegment& seg) { _list.push_back(seg); }
|
|
|
|
void erase() { _list.erase(_list.begin(), _list.end()); }
|
|
|
|
inline unsigned int size() const { return _list.size(); }
|
|
|
|
void draw() {
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
vector<LineSegment>::const_iterator it, end = _list.end();
|
|
|
|
for (it = _list.begin(); it != end; ++it)
|
|
|
|
it->draw();
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
vector<LineSegment> _list;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HUDText {
|
|
|
|
public:
|
2006-07-31 13:10:26 +00:00
|
|
|
HUDText(fntRenderer *f, float x, float y, const char *s, int align = 0, int digits = 0);
|
|
|
|
void draw();
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
private:
|
2006-07-31 13:10:26 +00:00
|
|
|
fntRenderer *_fnt;
|
2006-07-04 15:32:55 +00:00
|
|
|
float _x, _y;
|
|
|
|
int _digits;
|
|
|
|
static const int BUFSIZE = 64;
|
|
|
|
char _msg[BUFSIZE];
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TextList {
|
|
|
|
public:
|
|
|
|
TextList() { _font = 0; }
|
|
|
|
|
|
|
|
void setFont(fntRenderer *Renderer) { _font = Renderer; }
|
2006-07-31 13:10:26 +00:00
|
|
|
void add(float x, float y, const char *s, int align = 0, int digit = 0) {
|
|
|
|
_list.push_back(HUDText(_font, x, y, s, align, digit));
|
|
|
|
}
|
2006-07-04 15:32:55 +00:00
|
|
|
void erase() { _list.erase(_list.begin(), _list.end()); }
|
2006-08-01 15:31:15 +00:00
|
|
|
void align(const char *s, int align, float *x, float *y,
|
|
|
|
float *l, float *r, float *b, float *t) const;
|
|
|
|
void draw();
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
fntRenderer *_font;
|
|
|
|
vector<HUDText> _list;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HUD : public SGSubsystem, public SGPropertyChangeListener {
|
|
|
|
public:
|
|
|
|
HUD();
|
|
|
|
~HUD();
|
|
|
|
void init();
|
|
|
|
void update(double);
|
|
|
|
|
2010-10-22 19:11:24 +01:00
|
|
|
void reinit();
|
|
|
|
|
2006-07-04 15:32:55 +00:00
|
|
|
// called from Main/renderer.cxx to draw 2D and 3D HUD
|
2006-10-29 19:30:21 +00:00
|
|
|
void draw(osg::State&);
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
// listener callback to read various HUD related properties
|
|
|
|
void valueChanged(SGPropertyNode *);
|
|
|
|
// set current glColor
|
|
|
|
void setColor() const;
|
|
|
|
inline bool isVisible() const { return _visible; }
|
|
|
|
inline bool isAntialiased() const { return _antialiased; }
|
|
|
|
inline bool isTransparent() const { return _transparent; }
|
|
|
|
inline bool is3D() const { return _3Denabled; }
|
|
|
|
inline float alphaClamp() const { return _cl; }
|
|
|
|
inline double timer() const { return _timer; }
|
2006-08-01 21:16:56 +00:00
|
|
|
static void textAlign(fntRenderer *rend, const char *s, int align, float *x, float *y,
|
2006-08-01 15:31:15 +00:00
|
|
|
float *l, float *r, float *b, float *t);
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
enum Units { FEET, METER };
|
|
|
|
Units getUnits() const { return _units; }
|
|
|
|
|
|
|
|
enum {
|
2006-07-29 19:45:17 +00:00
|
|
|
HORIZONTAL = 0x0000, // keep that at zero?
|
|
|
|
VERTICAL = 0x0001,
|
|
|
|
TOP = 0x0002,
|
|
|
|
BOTTOM = 0x0004,
|
|
|
|
LEFT = 0x0008,
|
|
|
|
RIGHT = 0x0010,
|
2006-07-31 13:10:26 +00:00
|
|
|
NOTICKS = 0x0020,
|
|
|
|
NOTEXT = 0x0040,
|
2006-07-29 19:45:17 +00:00
|
|
|
BOTH = (LEFT|RIGHT),
|
2006-08-01 15:31:15 +00:00
|
|
|
|
|
|
|
// for alignment (with LEFT, RIGHT, TOP, BOTTOM)
|
|
|
|
HCENTER = 0x0080,
|
|
|
|
VCENTER = 0x0100,
|
|
|
|
CENTER = (HCENTER|VCENTER),
|
2006-07-04 15:32:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void common_draw();
|
|
|
|
int load(const char *, float x = 320.0f, float y = 240.0f,
|
2008-07-25 18:38:29 +00:00
|
|
|
int level = 0, const std::string& indent = "");
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
private:
|
2010-10-22 19:11:24 +01:00
|
|
|
void deinit();
|
|
|
|
|
2006-07-04 15:32:55 +00:00
|
|
|
void draw3D();
|
|
|
|
void draw2D(GLfloat, GLfloat, GLfloat, GLfloat);
|
|
|
|
|
2010-12-02 00:41:29 +00:00
|
|
|
void currentColorChanged();
|
|
|
|
|
2006-07-04 15:32:55 +00:00
|
|
|
class Input;
|
|
|
|
class Item;
|
|
|
|
class Label;
|
|
|
|
class Scale;
|
|
|
|
class Gauge;
|
|
|
|
class Tape;
|
|
|
|
class Dial;
|
|
|
|
class TurnBankIndicator;
|
|
|
|
class Ladder;
|
|
|
|
class Runway;
|
2006-07-22 08:00:56 +00:00
|
|
|
class AimingReticle;
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
deque<Item *> _items;
|
2008-07-29 15:41:25 +00:00
|
|
|
deque<Item *> _ladders;
|
2006-07-04 15:32:55 +00:00
|
|
|
|
2011-12-11 14:12:17 +00:00
|
|
|
SGPropertyNode_ptr _currentPath;
|
|
|
|
SGPropertyNode_ptr _currentColor;
|
2006-07-04 15:32:55 +00:00
|
|
|
SGPropertyNode_ptr _visibility;
|
|
|
|
SGPropertyNode_ptr _3DenabledN;
|
|
|
|
SGPropertyNode_ptr _antialiasing;
|
|
|
|
SGPropertyNode_ptr _transparency;
|
|
|
|
SGPropertyNode_ptr _red, _green, _blue, _alpha;
|
|
|
|
SGPropertyNode_ptr _alpha_clamp;
|
|
|
|
SGPropertyNode_ptr _brightness;
|
|
|
|
bool _visible;
|
|
|
|
bool _3Denabled;
|
|
|
|
bool _antialiased;
|
|
|
|
bool _transparent;
|
|
|
|
float _r, _g, _b, _a, _cl;
|
|
|
|
|
|
|
|
SGPropertyNode_ptr _scr_widthN, _scr_heightN;
|
|
|
|
int _scr_width, _scr_height;
|
|
|
|
SGPropertyNode_ptr _unitsN;
|
|
|
|
Units _units;
|
|
|
|
double _timer;
|
|
|
|
|
|
|
|
fntRenderer *_font_renderer;
|
|
|
|
FGFontCache *_font_cache;
|
|
|
|
fntTexFont *_font;
|
|
|
|
float _font_size;
|
|
|
|
int _style;
|
2009-03-11 19:10:12 +00:00
|
|
|
bool _listener_active;
|
2006-07-04 15:32:55 +00:00
|
|
|
|
2008-07-29 15:41:25 +00:00
|
|
|
ClipBox *_clip_box;
|
2006-07-04 15:32:55 +00:00
|
|
|
TextList _text_list;
|
|
|
|
LineList _line_list;
|
|
|
|
LineList _stipple_line_list;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HUD::Input {
|
|
|
|
public:
|
|
|
|
Input(const SGPropertyNode *n, float factor = 1.0, float offset = 0.0,
|
|
|
|
float min = -SGLimitsf::max(), float max = SGLimitsf::max()) :
|
|
|
|
_valid(false),
|
|
|
|
_property(0),
|
|
|
|
_damped(SGLimitsf::max())
|
|
|
|
{
|
|
|
|
if (!n)
|
|
|
|
return;
|
|
|
|
_factor = n->getFloatValue("factor", factor);
|
|
|
|
_offset = n->getFloatValue("offset", offset);
|
|
|
|
_min = n->getFloatValue("min", min);
|
|
|
|
_max = n->getFloatValue("max", max);
|
2011-05-22 16:30:18 +01:00
|
|
|
_coeff = 1.0 - 1.0 / powf(10, fabs(n->getFloatValue("damp", 0.0)));
|
2006-07-04 15:32:55 +00:00
|
|
|
SGPropertyNode *p = ((SGPropertyNode *)n)->getNode("property", false);
|
|
|
|
if (p) {
|
|
|
|
const char *path = p->getStringValue();
|
|
|
|
if (path && path[0]) {
|
|
|
|
_property = fgGetNode(path, true);
|
|
|
|
_valid = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-22 08:00:56 +00:00
|
|
|
bool getBoolValue() const {
|
|
|
|
assert(_property);
|
|
|
|
return _property->getBoolValue();
|
|
|
|
}
|
|
|
|
|
2006-07-04 15:32:55 +00:00
|
|
|
const char *getStringValue() const {
|
|
|
|
assert(_property);
|
|
|
|
return _property->getStringValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
float getFloatValue() {
|
|
|
|
assert(_property);
|
|
|
|
float f = _property->getFloatValue() * _factor + _offset;
|
|
|
|
if (_damped == SGLimitsf::max())
|
|
|
|
_damped = f;
|
|
|
|
if (_coeff > 0.0f)
|
|
|
|
f = _damped = f * (1.0f - _coeff) + _damped * _coeff;
|
2006-07-05 22:55:33 +00:00
|
|
|
return clamp(f);
|
2006-07-04 15:32:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline float isValid() const { return _valid; }
|
|
|
|
inline float min() const { return _min; }
|
|
|
|
inline float max() const { return _max; }
|
|
|
|
inline float factor() const { return _factor; }
|
2006-07-05 22:55:33 +00:00
|
|
|
float clamp(float v) const { return v < _min ? _min : v > _max ? _max : v; }
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
void set_min(float m, bool force = true) {
|
|
|
|
if (force || _min == -SGLimitsf::max())
|
|
|
|
_min = m;
|
|
|
|
}
|
|
|
|
void set_max(float m, bool force = true) {
|
|
|
|
if (force || _max == SGLimitsf::max())
|
|
|
|
_max = m;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool _valid;
|
|
|
|
SGConstPropertyNode_ptr _property;
|
|
|
|
float _factor;
|
|
|
|
float _offset;
|
|
|
|
float _min;
|
|
|
|
float _max;
|
|
|
|
float _coeff;
|
|
|
|
float _damped;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-07-05 22:55:33 +00:00
|
|
|
class HUD::Item {
|
2006-07-04 15:32:55 +00:00
|
|
|
public:
|
|
|
|
Item(HUD *parent, const SGPropertyNode *, float x = 0.0f, float y = 0.0f);
|
|
|
|
virtual ~Item () {}
|
|
|
|
virtual void draw() = 0;
|
|
|
|
virtual bool isEnabled();
|
|
|
|
|
|
|
|
protected:
|
2006-08-01 21:11:38 +00:00
|
|
|
enum Format {
|
|
|
|
INVALID,
|
|
|
|
NONE,
|
|
|
|
INT,
|
|
|
|
LONG,
|
|
|
|
FLOAT,
|
|
|
|
DOUBLE,
|
|
|
|
STRING,
|
|
|
|
};
|
|
|
|
|
|
|
|
Format check_format(const char *) const;
|
2006-07-04 15:32:55 +00:00
|
|
|
inline float get_span() const { return _scr_span; }
|
|
|
|
inline int get_digits() const { return _digits; }
|
|
|
|
|
2006-07-29 19:45:17 +00:00
|
|
|
inline bool option_vert() const { return (_options & VERTICAL) == VERTICAL; }
|
2006-07-05 06:28:37 +00:00
|
|
|
inline bool option_left() const { return (_options & LEFT) == LEFT; }
|
|
|
|
inline bool option_right() const { return (_options & RIGHT) == RIGHT; }
|
2006-07-04 15:32:55 +00:00
|
|
|
inline bool option_both() const { return (_options & BOTH) == BOTH; }
|
2006-07-05 06:28:37 +00:00
|
|
|
inline bool option_noticks() const { return (_options & NOTICKS) == NOTICKS; }
|
|
|
|
inline bool option_notext() const { return (_options & NOTEXT) == NOTEXT; }
|
|
|
|
inline bool option_top() const { return (_options & TOP) == TOP; }
|
|
|
|
inline bool option_bottom() const { return (_options & BOTTOM) == BOTTOM; }
|
2006-07-04 15:32:55 +00:00
|
|
|
|
2006-07-31 13:10:26 +00:00
|
|
|
void draw_line(float x1, float y1, float x2, float y2);
|
|
|
|
void draw_stipple_line(float x1, float y1, float x2, float y2);
|
2008-07-28 17:04:24 +00:00
|
|
|
void draw_text(float x, float y, const char *msg, int align = 0, int digit = 0);
|
2006-07-04 21:04:22 +00:00
|
|
|
void draw_circle(float x1, float y1, float r) const;
|
2010-02-05 08:45:15 +00:00
|
|
|
void draw_arc(float x1, float y1, float t0, float t1, float r) const;
|
2006-07-04 21:04:22 +00:00
|
|
|
void draw_bullet(float, float, float);
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
HUD *_hud;
|
2008-07-25 18:38:29 +00:00
|
|
|
std::string _name;
|
2006-07-04 15:32:55 +00:00
|
|
|
int _options;
|
2006-07-06 14:30:18 +00:00
|
|
|
float _x, _y, _w, _h;
|
2006-07-22 10:09:36 +00:00
|
|
|
float _center_x, _center_y;
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
private:
|
2008-01-24 23:05:58 +00:00
|
|
|
SGSharedPtr<SGCondition> _condition;
|
2006-07-04 15:32:55 +00:00
|
|
|
float _disp_factor; // Multiply by to get numbers shown on scale.
|
|
|
|
float _scr_span; // Working values for draw;
|
|
|
|
int _digits;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HUD::Label : public Item {
|
|
|
|
public:
|
|
|
|
Label(HUD *parent, const SGPropertyNode *, float x, float y);
|
|
|
|
virtual void draw();
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool blink();
|
|
|
|
|
|
|
|
Input _input;
|
|
|
|
Format _mode;
|
2008-07-25 18:38:29 +00:00
|
|
|
std::string _format;
|
2006-07-31 13:10:26 +00:00
|
|
|
int _halign; // HUDText alignment
|
2006-07-04 15:32:55 +00:00
|
|
|
int _blink;
|
|
|
|
bool _box;
|
2006-07-24 16:00:18 +00:00
|
|
|
float _text_y;
|
2006-07-25 07:07:34 +00:00
|
|
|
float _pointer_width;
|
|
|
|
float _pointer_length;
|
2006-07-04 15:32:55 +00:00
|
|
|
|
2008-01-24 23:05:58 +00:00
|
|
|
SGSharedPtr<SGCondition> _blink_condition;
|
2006-07-04 15:32:55 +00:00
|
|
|
double _blink_interval;
|
|
|
|
double _blink_target; // time for next blink state change
|
|
|
|
bool _blink_state;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// abstract base class for both moving scale and moving needle (fixed scale)
|
|
|
|
// indicators.
|
|
|
|
//
|
|
|
|
class HUD::Scale : public Item {
|
|
|
|
public:
|
|
|
|
Scale(HUD *parent, const SGPropertyNode *, float x, float y);
|
|
|
|
virtual void draw ( void ) {} // No-op here. Defined in derived classes.
|
|
|
|
|
|
|
|
protected:
|
2006-07-05 22:55:33 +00:00
|
|
|
inline float factor() const { return _display_factor; }
|
|
|
|
inline float range_to_show() const { return _range_shown; }
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
Input _input;
|
2006-07-06 16:46:25 +00:00
|
|
|
float _major_divs; // major division marker units
|
|
|
|
float _minor_divs; // minor division marker units
|
|
|
|
unsigned int _modulo; // Roll over point
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
float _range_shown; // Width Units.
|
2006-07-05 22:55:33 +00:00
|
|
|
float _display_factor; // factor => screen units/range values.
|
2006-07-04 15:32:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class HUD::Gauge : public Scale {
|
|
|
|
public:
|
|
|
|
Gauge(HUD *parent, const SGPropertyNode *, float x, float y);
|
|
|
|
virtual void draw();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// displays the indicated quantity on a scale that moves past the
|
|
|
|
// pointer. It may be horizontal or vertical.
|
|
|
|
//
|
|
|
|
class HUD::Tape : public Scale {
|
|
|
|
public:
|
|
|
|
Tape(HUD *parent, const SGPropertyNode *, float x, float y);
|
|
|
|
virtual void draw();
|
|
|
|
|
|
|
|
protected:
|
2006-08-02 15:34:33 +00:00
|
|
|
void draw_vertical(float);
|
|
|
|
void draw_horizontal(float);
|
2006-07-31 17:36:27 +00:00
|
|
|
void draw_fixed_pointer(float, float, float, float, float, float);
|
2006-08-01 21:11:38 +00:00
|
|
|
char *format_value(float);
|
2006-07-04 15:32:55 +00:00
|
|
|
|
|
|
|
private:
|
2006-07-04 17:25:14 +00:00
|
|
|
float _val_span;
|
|
|
|
float _half_width_units;
|
|
|
|
bool _draw_tick_bottom;
|
|
|
|
bool _draw_tick_top;
|
|
|
|
bool _draw_tick_right;
|
|
|
|
bool _draw_tick_left;
|
|
|
|
bool _draw_cap_bottom;
|
|
|
|
bool _draw_cap_top;
|
|
|
|
bool _draw_cap_right;
|
|
|
|
bool _draw_cap_left;
|
|
|
|
float _marker_offset;
|
2009-03-12 00:05:45 +00:00
|
|
|
float _label_offset;
|
2006-07-31 19:25:41 +00:00
|
|
|
float _label_gap;
|
2006-07-04 17:25:14 +00:00
|
|
|
bool _pointer;
|
2006-08-01 21:11:38 +00:00
|
|
|
Format _label_fmt;
|
2008-07-25 18:38:29 +00:00
|
|
|
std::string _format;
|
2006-08-02 15:34:33 +00:00
|
|
|
int _div_ratio; // _major_divs/_minor_divs
|
|
|
|
bool _odd_type; // whether to put numbers at 0/2/4 or 1/3/5
|
2006-07-24 16:00:18 +00:00
|
|
|
|
2006-08-01 21:11:38 +00:00
|
|
|
enum { BUFSIZE = 64 };
|
|
|
|
char _buf[BUFSIZE];
|
|
|
|
|
2006-07-04 17:25:14 +00:00
|
|
|
enum PointerType { FIXED, MOVING } _pointer_type;
|
|
|
|
enum TickType { LINE, CIRCLE } _tick_type;
|
|
|
|
enum TickLength { VARIABLE, CONSTANT } _tick_length;
|
2006-07-04 15:32:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HUD::Dial : public Scale {
|
|
|
|
public:
|
|
|
|
Dial(HUD *parent, const SGPropertyNode *, float x, float y);
|
|
|
|
virtual void draw();
|
|
|
|
|
|
|
|
private:
|
|
|
|
float _radius;
|
|
|
|
int _divisions;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HUD::TurnBankIndicator : public Item {
|
|
|
|
public:
|
|
|
|
TurnBankIndicator(HUD *parent, const SGPropertyNode *, float x, float y);
|
|
|
|
virtual void draw();
|
|
|
|
|
|
|
|
private:
|
2006-07-27 23:34:11 +00:00
|
|
|
void draw_scale();
|
|
|
|
void draw_tee();
|
2006-07-28 10:11:34 +00:00
|
|
|
void draw_line(float, float, float, float);
|
2006-07-27 23:34:11 +00:00
|
|
|
void draw_tick(float angle, float r1, float r2, int side);
|
|
|
|
|
2006-07-04 15:32:55 +00:00
|
|
|
Input _bank;
|
|
|
|
Input _sideslip;
|
|
|
|
|
|
|
|
float _gap_width;
|
|
|
|
bool _bank_scale;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HUD::Ladder : public Item {
|
|
|
|
public:
|
|
|
|
Ladder(HUD *parent, const SGPropertyNode *, float x, float y);
|
2008-07-29 15:41:25 +00:00
|
|
|
~Ladder();
|
2006-07-04 15:32:55 +00:00
|
|
|
virtual void draw();
|
|
|
|
|
|
|
|
private:
|
2006-07-24 16:00:18 +00:00
|
|
|
void draw_zenith(float, float);
|
|
|
|
void draw_nadir(float, float);
|
2006-07-04 15:32:55 +00:00
|
|
|
|
2008-07-28 17:04:24 +00:00
|
|
|
void draw_text(float x, float y, const char *s, int align = 0) {
|
2006-07-31 13:10:26 +00:00
|
|
|
_locTextList.add(x, y, s, align, 0);
|
2006-07-04 15:32:55 +00:00
|
|
|
}
|
|
|
|
|
2008-07-28 17:04:24 +00:00
|
|
|
void draw_line(float x1, float y1, float x2, float y2, bool stipple = false) {
|
|
|
|
if (stipple)
|
|
|
|
_locStippleLineList.add(LineSegment(x1, y1, x2, y2));
|
|
|
|
else
|
|
|
|
_locLineList.add(LineSegment(x1, y1, x2, y2));
|
2006-07-04 15:32:55 +00:00
|
|
|
}
|
|
|
|
|
2006-07-11 16:09:35 +00:00
|
|
|
enum Type { PITCH, CLIMB_DIVE } _type;
|
2006-07-04 15:32:55 +00:00
|
|
|
Input _pitch;
|
|
|
|
Input _roll;
|
2006-07-11 16:09:35 +00:00
|
|
|
float _width_units;
|
|
|
|
int _div_units;
|
2008-07-28 17:04:24 +00:00
|
|
|
float _scr_hole;
|
|
|
|
float _zero_bar_overlength;
|
|
|
|
bool _dive_bar_angle;
|
|
|
|
float _tick_length;
|
2006-07-04 15:32:55 +00:00
|
|
|
float _vmax;
|
|
|
|
float _vmin;
|
|
|
|
float _compression;
|
2006-07-28 18:37:33 +00:00
|
|
|
bool _dynamic_origin;
|
2006-07-05 22:55:33 +00:00
|
|
|
bool _frl; // fuselage reference line
|
2006-07-04 15:32:55 +00:00
|
|
|
bool _target_spot;
|
2006-07-27 02:46:14 +00:00
|
|
|
bool _target_markers;
|
2006-07-04 15:32:55 +00:00
|
|
|
bool _velocity_vector;
|
|
|
|
bool _drift_marker;
|
|
|
|
bool _alpha_bracket;
|
|
|
|
bool _energy_marker;
|
|
|
|
bool _climb_dive_marker;
|
|
|
|
bool _glide_slope_marker;
|
|
|
|
float _glide_slope;
|
|
|
|
bool _energy_worm;
|
|
|
|
bool _waypoint_marker;
|
2006-07-23 08:14:03 +00:00
|
|
|
bool _zenith;
|
|
|
|
bool _nadir;
|
|
|
|
bool _hat;
|
2006-07-04 15:32:55 +00:00
|
|
|
|
2008-07-29 15:41:25 +00:00
|
|
|
ClipBox *_clip_box;
|
2006-07-04 15:32:55 +00:00
|
|
|
// The Ladder has its own temporary display lists
|
|
|
|
TextList _locTextList;
|
|
|
|
LineList _locLineList;
|
|
|
|
LineList _locStippleLineList;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// responsible for rendering the active runway in the hud (if visible).
|
|
|
|
//
|
|
|
|
class HUD::Runway : public Item {
|
|
|
|
public:
|
|
|
|
Runway(HUD *parent, const SGPropertyNode *, float x, float y);
|
|
|
|
virtual void draw();
|
|
|
|
|
|
|
|
private:
|
|
|
|
void boundPoint(const sgdVec3& v, sgdVec3& m);
|
|
|
|
bool boundOutsidePoints(sgdVec3& v, sgdVec3& m);
|
2006-07-05 22:55:33 +00:00
|
|
|
bool drawLine(const sgdVec3& a1, const sgdVec3& a2, const sgdVec3& p1, const sgdVec3& p2);
|
2006-07-04 15:32:55 +00:00
|
|
|
void drawArrow();
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
FGRunway* get_active_runway();
|
2006-07-04 15:32:55 +00:00
|
|
|
void get_rwy_points(sgdVec3 *points);
|
|
|
|
void setLineWidth();
|
|
|
|
|
|
|
|
SGPropertyNode_ptr _agl;
|
|
|
|
sgdVec3 _points3d[6], _points2d[6];
|
|
|
|
double _mm[16];
|
|
|
|
double _pm[16];
|
|
|
|
double _arrow_scale; // scales of runway indication arrow
|
|
|
|
double _arrow_radius;
|
|
|
|
double _line_scale; // maximum line scale
|
|
|
|
double _scale_dist; // distance where to start scaling the lines
|
|
|
|
double _default_pitch;
|
|
|
|
double _default_heading;
|
|
|
|
GLint _view[4];
|
James Turner:
Convert FGRunway to be heap-based, and inherit FGPositioned. This is a large, ugly change, since FGRunway was essentially a plain struct, with no accessors or abstraction. This change adds various helpers and accessors to FGRunway, but doesn't change many places to use them - that will be a follow up series of patches. It's still a large patch, but outside of FGAirport and FGRunway, mostly mechanical search-and-replace.
An interesting part of this change is that reciprocal runways now exist as independent objects, rather than being created on the fly by the search methods. This simplifies some pieces of code that search for and iterate runways. For users who only want one 'end' of a runway, the new 'isReciprocal' predicate allows them to ignore the 'other' end. Current the only user of this is the 'ground-radar' ATC feature. If we had data on which runways are truly 'single-ended', it would now be trivial to use this in the airport loader to *not* create the reciprocal.
2008-09-11 08:38:09 +00:00
|
|
|
FGRunway* _runway;
|
2006-07-04 15:32:55 +00:00
|
|
|
unsigned short _stipple_out; // stipple pattern of the outline of the runway
|
|
|
|
unsigned short _stipple_center; // stipple pattern of the center line of the runway
|
|
|
|
bool _draw_arrow; // draw arrow when runway is not visible in HUD
|
|
|
|
bool _draw_arrow_always; // always draws arrow
|
2006-07-06 14:30:18 +00:00
|
|
|
float _left, _right, _top, _bottom;
|
2006-07-04 15:32:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2006-07-22 08:00:56 +00:00
|
|
|
class HUD::AimingReticle : public Item {
|
|
|
|
public:
|
|
|
|
AimingReticle(HUD *parent, const SGPropertyNode *, float x, float y);
|
|
|
|
virtual void draw();
|
|
|
|
|
|
|
|
private:
|
2008-01-24 23:05:58 +00:00
|
|
|
SGSharedPtr<SGCondition> _active_condition; // stadiametric (true) or standby (false)
|
2010-02-05 08:45:15 +00:00
|
|
|
SGSharedPtr<SGCondition> _tachy_condition; // tachymetric (true) or standby (false)
|
|
|
|
SGSharedPtr<SGCondition> _align_condition; // tachymetric (true) or standby (false)
|
|
|
|
|
2006-07-22 08:00:56 +00:00
|
|
|
Input _diameter; // inner/outer radius relation
|
2010-02-05 08:45:15 +00:00
|
|
|
Input _pitch;
|
|
|
|
Input _yaw;
|
|
|
|
Input _speed;
|
|
|
|
Input _range;
|
|
|
|
Input _t0;
|
|
|
|
Input _t1;
|
|
|
|
Input _offset_x;
|
|
|
|
Input _offset_y;
|
|
|
|
|
2006-07-22 08:00:56 +00:00
|
|
|
float _bullet_size;
|
|
|
|
float _inner_radius;
|
2010-02-05 08:45:15 +00:00
|
|
|
float _compression;
|
|
|
|
float _limit_x;
|
|
|
|
float _limit_y;
|
|
|
|
|
2006-07-22 08:00:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2006-07-04 15:32:55 +00:00
|
|
|
#endif // _HUD_HXX
|