]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/hud_ladr.cxx
4b3a881727b5eff0a4c9f6da0f94acfe0f8a9915
[flightgear.git] / src / Cockpit / hud_ladr.cxx
1 #ifdef HAVE_CONFIG_H
2 #  include "config.h"
3 #endif
4
5 #include <simgear/constants.h>
6
7 #include "hud.hxx"
8 #include "panel.hxx"
9
10
11 // FIXME
12 extern float get_roll(void);
13 extern float get_pitch(void);
14
15
16 HudLadder::HudLadder(const SGPropertyNode *node) :
17     dual_instr_item(
18             node->getIntValue("x"),
19             node->getIntValue("y"),
20             node->getIntValue("width"),
21             node->getIntValue("height"),
22             get_roll,
23             get_pitch,                          // FIXME getter functions from cockpit.cxx
24             node->getBoolValue("working"),
25             HUDS_RIGHT),
26     width_units(int(node->getFloatValue("span_units"))),
27     div_units(int(fabs(node->getFloatValue("division_units")))),
28     minor_div(0 /* hud.cxx: static float minor_division = 0 */),
29     label_pos(node->getIntValue("lbl_pos")),
30     scr_hole(node->getIntValue("screen_hole")),
31     factor(node->getFloatValue("compression_factor")),
32     hudladder_type(node->getStringValue("name")),
33     frl(node->getBoolValue("enable_frl", false)),
34     target_spot(node->getBoolValue("enable_target_spot", false)),
35     velocity_vector(node->getBoolValue("enable_velocity_vector", false)),
36     drift_marker(node->getBoolValue("enable_drift_marker", false)),
37     alpha_bracket(node->getBoolValue("enable_alpha_bracket", false)),
38     energy_marker(node->getBoolValue("enable_energy_marker", false)),
39     climb_dive_marker(node->getBoolValue("enable_climb_dive_marker", false)),
40     glide_slope_marker(node->getBoolValue("enable_glide_slope_marker",false)),
41     glide_slope(node->getFloatValue("glide_slope", -4.0)),
42     energy_worm(node->getBoolValue("enable_energy_marker", false)),
43     waypoint_marker(node->getBoolValue("enable_waypoint_marker", false)),
44     zenith(node->getIntValue("zenith")),
45     nadir(node->getIntValue("nadir")),
46     hat(node->getIntValue("hat"))
47 {
48     // The factor assumes a base of 55 degrees per 640 pixels.
49     // Invert to convert the "compression" factor to a
50     // pixels-per-degree number.
51     if (fgGetBool("/sim/hud/enable3d", true) && HUD_style == 1)
52         factor = (640./55.);
53
54     SG_LOG(SG_INPUT, SG_INFO, "Done reading HudLadder instrument");     // TODO add name
55
56     if (!width_units)
57         width_units = 45;
58
59     vmax = width_units / 2;
60     vmin = -vmax;
61 }
62
63
64 HudLadder::~HudLadder()
65 {
66 }
67
68
69 //
70 //  Draws a climb ladder in the center of the HUD
71 //
72
73 void HudLadder::draw(void)
74 {
75
76     float x_ini, x_ini2;
77     float x_end, x_end2;
78     float y = 0;
79     int count;
80     float cosine, sine, xvvr, yvvr, Vxx = 0.0, Vyy = 0.0, Vzz = 0.0;
81     float up_vel, ground_vel, actslope = 0.0;
82     float Axx = 0.0, Ayy = 0.0, Azz = 0.0, total_vel = 0.0, pot_slope, t1;
83     float t2 = 0.0, psi = 0.0, alpha, pla;
84     float vel_x = 0.0, vel_y = 0.0, drift;
85     bool pitch_ladder = false;
86     bool climb_dive_ladder = false;
87     bool clip_plane = false;
88
89     GLdouble eqn_top[4] = {0.0, -1.0, 0.0, 0.0};
90     GLdouble eqn_left[4] = {-1.0, 0.0, 0.0, 100.0};
91     GLdouble eqn_right[4] = {1.0, 0.0, 0.0, 100.0};
92
93     POINT centroid = get_centroid();
94     RECT box = get_location();
95
96     float half_span  = box.right / 2.0;
97     float roll_value = current_ch2();
98     alpha = get_aoa();
99     pla = get_throttleval();
100
101 #ifdef ENABLE_SP_FMDS
102     int lgear, wown, wowm, ilcanclaw, ihook;
103     ilcanclaw = get_iaux2();
104     lgear = get_iaux3();
105     wown = get_iaux4();
106     wowm = get_iaux5();
107     ihook = get_iaux6();
108 #endif
109     float pitch_value = current_ch1() * SGD_RADIANS_TO_DEGREES;
110
111     if (hudladder_type == "Climb/Dive Ladder") {
112         pitch_ladder = false;
113         climb_dive_ladder = true;
114         clip_plane = true;
115
116     } else { // hudladder_type == "Pitch Ladder"
117         pitch_ladder = true;
118         climb_dive_ladder = false;
119         clip_plane = false;
120     }
121
122     //**************************************************************
123     glPushMatrix();
124     // define (0, 0) as center of screen
125     glTranslatef(centroid.x, centroid.y, 0);
126
127     // OBJECT STATIC RETICLE
128     // TYPE FRL
129     // ATTRIB - ALWAYS
130     // Draw the FRL spot and line
131     if (frl) {
132 #define FRL_DIAMOND_SIZE 2.0
133         glBegin(GL_LINE_LOOP);
134         glVertex2f(-FRL_DIAMOND_SIZE, 0.0);
135         glVertex2f(0.0, FRL_DIAMOND_SIZE);
136         glVertex2f(FRL_DIAMOND_SIZE, 0.0);
137         glVertex2f(0.0, -FRL_DIAMOND_SIZE);
138         glEnd();
139
140         glBegin(GL_LINE_STRIP);
141         glVertex2f(0, FRL_DIAMOND_SIZE);
142         glVertex2f(0, 8.0);
143         glEnd();
144 #undef FRL_DIAMOND_SIZE
145     }
146     // TYPE WATERLINE_MARK (W shaped _    _ )
147     //                                    \/\/
148
149     //****************************************************************
150     // TYPE TARGET_SPOT
151     // Draw the target spot.
152     if (target_spot) {
153 #define CENTER_DIAMOND_SIZE 6.0
154         glBegin(GL_LINE_LOOP);
155         glVertex2f(-CENTER_DIAMOND_SIZE, 0.0);
156         glVertex2f(0.0, CENTER_DIAMOND_SIZE);
157         glVertex2f(CENTER_DIAMOND_SIZE, 0.0);
158         glVertex2f(0.0, -CENTER_DIAMOND_SIZE);
159         glEnd();
160 #undef CENTER_DIAMOND_SIZE
161     }
162
163     //****************************************************************
164     //velocity vector reticle - computations
165     if (velocity_vector) {
166         Vxx = get_Vx();
167         Vyy = get_Vy();
168         Vzz = get_Vz();
169         Axx = get_Ax();
170         Ayy = get_Ay();
171         Azz = get_Az();
172         psi = get_heading();
173
174         if (psi > 180.0)
175             psi = psi - 360;
176
177         total_vel = sqrt(Vxx * Vxx + Vyy * Vyy + Vzz * Vzz);
178         ground_vel = sqrt(Vxx * Vxx + Vyy * Vyy);
179         up_vel = Vzz;
180
181         if (ground_vel < 2.0) {
182             if (fabs(up_vel) < 2.0)
183                 actslope = 0.0;
184             else
185                 actslope = (up_vel / fabs(up_vel)) * 90.0;
186
187         } else {
188             actslope = atan(up_vel / ground_vel) * SGD_RADIANS_TO_DEGREES;
189         }
190
191         xvvr = (((atan2(Vyy, Vxx) * SGD_RADIANS_TO_DEGREES) - psi)
192                 * (factor / globals->get_current_view()->get_aspect_ratio()));
193         drift = ((atan2(Vyy, Vxx) * SGD_RADIANS_TO_DEGREES) - psi);
194         yvvr = ((actslope - pitch_value) * factor);
195         vel_y = ((actslope - pitch_value) * cos(roll_value) + drift * sin(roll_value)) * factor;
196         vel_x = (-(actslope - pitch_value) * sin(roll_value) + drift * cos(roll_value))
197                 * (factor/globals->get_current_view()->get_aspect_ratio());
198         //  printf("%f %f %f %f\n",vel_x, vel_y, drift, psi);
199
200         //****************************************************************
201         // OBJECT MOVING RETICLE
202         // TYPE - DRIFT MARKER
203         // ATTRIB - ALWAYS
204         // drift marker
205         if (drift_marker) {
206             glBegin(GL_LINE_STRIP);
207             glVertex2f((xvvr * 25 / 120) - 6, -4);
208             glVertex2f(xvvr * 25 / 120, 8);
209             glVertex2f((xvvr * 25 / 120) + 6, -4);
210             glEnd();
211         }
212
213         //****************************************************************
214         // Clipping coordinates for ladder to be input from xml file
215         // Clip hud ladder
216         if (clip_plane) {
217             glClipPlane(GL_CLIP_PLANE0, eqn_top);
218             glEnable(GL_CLIP_PLANE0);
219             glClipPlane(GL_CLIP_PLANE1, eqn_left);
220             glEnable(GL_CLIP_PLANE1);
221             glClipPlane(GL_CLIP_PLANE2, eqn_right);
222             glEnable(GL_CLIP_PLANE2);
223             // glScissor(-100,-240, 200, 240);
224             // glEnable(GL_SCISSOR_TEST);
225         }
226
227         //****************************************************************
228         // OBJECT MOVING RETICLE
229         // TYPE VELOCITY VECTOR
230         // ATTRIB - ALWAYS
231         // velocity vector
232         glBegin(GL_LINE_LOOP);  // Use polygon to approximate a circle
233         for (count = 0; count < 50; count++) {
234             cosine = 6 * cos(count * SGD_2PI / 50.0);
235             sine =   6 * sin(count * SGD_2PI / 50.0);
236             glVertex2f(cosine + vel_x, sine + vel_y);
237         }
238         glEnd();
239
240         //velocity vector reticle orientation lines
241         glBegin(GL_LINE_STRIP);
242         glVertex2f(vel_x - 12, vel_y);
243         glVertex2f(vel_x - 6, vel_y);
244         glEnd();
245         glBegin(GL_LINE_STRIP);
246         glVertex2f(vel_x + 12, vel_y);
247         glVertex2f(vel_x + 6, vel_y);
248         glEnd();
249         glBegin(GL_LINE_STRIP);
250         glVertex2f(vel_x, vel_y + 12);
251         glVertex2f(vel_x, vel_y + 6);
252         glEnd();
253
254 #ifdef ENABLE_SP_FMDS
255         // OBJECT MOVING RETICLE
256         // TYPE LINE
257         // ATTRIB - ON CONDITION
258         if (lgear == 1) {
259             // undercarriage status
260             glBegin(GL_LINE_STRIP);
261             glVertex2f(vel_x + 8, vel_y);
262             glVertex2f(vel_x + 8, vel_y - 4);
263             glEnd();
264
265             // OBJECT MOVING RETICLE
266             // TYPE LINE
267             // ATTRIB - ON CONDITION
268             glBegin(GL_LINE_STRIP);
269             glVertex2f(vel_x - 8, vel_y);
270             glVertex2f(vel_x - 8, vel_y - 4);
271             glEnd();
272
273             // OBJECT MOVING RETICLE
274             // TYPE LINE
275             // ATTRIB - ON CONDITION
276             glBegin(GL_LINE_STRIP);
277             glVertex2f(vel_x, vel_y - 6);
278             glVertex2f(vel_x, vel_y - 10);
279             glEnd();
280         }
281
282         // OBJECT MOVING RETICLE
283         // TYPE V
284         // ATTRIB - ON CONDITION
285         if (ihook == 1) {
286             // arrestor hook status
287             glBegin(GL_LINE_STRIP);
288             glVertex2f(vel_x - 4, vel_y - 8);
289             glVertex2f(vel_x, vel_y - 10);
290             glVertex2f(vel_x + 4, vel_y - 8);
291             glEnd();
292         }
293 #endif
294     } // if velocity_vector
295
296
297     //***************************************************************
298     // OBJECT MOVING RETICLE
299     // TYPE - SQUARE_BRACKET
300     // ATTRIB - ON CONDITION
301     // alpha bracket
302 #ifdef ENABLE_SP_FMDS
303     if (alpha_bracket && ihook == 1) {
304         glBegin(GL_LINE_STRIP);
305         glVertex2f(vel_x - 20 , vel_y - (16 - alpha) * factor);
306         glVertex2f(vel_x - 17, vel_y - (16 - alpha) * factor);
307         glVertex2f(vel_x - 17, vel_y - (14 - alpha) * factor);
308         glVertex2f(vel_x - 20, vel_y - (14 - alpha) * factor);
309         glEnd();
310
311         glBegin(GL_LINE_STRIP);
312         glVertex2f(vel_x + 20 , vel_y - (16 - alpha) * factor);
313         glVertex2f(vel_x + 17, vel_y - (16 - alpha) * factor);
314         glVertex2f(vel_x + 17, vel_y - (14 - alpha) * factor);
315         glVertex2f(vel_x + 20, vel_y - (14 - alpha) * factor);
316         glEnd();
317     }
318 #endif
319     //printf("xvr=%f, yvr=%f, Vx=%f, Vy=%f, Vz=%f\n",xvvr, yvvr, Vx, Vy, Vz);
320     //printf("Ax=%f, Ay=%f, Az=%f\n",Ax, Ay, Az);
321
322     //****************************************************************
323     // OBJECT MOVING RETICLE
324     // TYPE ENERGY_MARKERS
325     // ATTRIB - ALWAYS
326     //energy markers - compute potential slope
327     if (energy_marker) {
328         if (total_vel < 5.0) {
329             t1 = 0;
330             t2 = 0;
331         } else {
332             t1 = up_vel / total_vel;
333             t2 = asin((Vxx * Axx + Vyy * Ayy + Vzz * Azz) / (9.81 * total_vel));
334         }
335         pot_slope = ((t2 / 3) * SGD_RADIANS_TO_DEGREES) * factor + vel_y;
336         // if (pot_slope < (vel_y - 45)) pot_slope = vel_y - 45;
337         // if (pot_slope > (vel_y + 45)) pot_slope = vel_y + 45;
338
339         //energy markers
340         glBegin(GL_LINE_STRIP);
341         glVertex2f(vel_x - 20, pot_slope - 5);
342         glVertex2f(vel_x - 15, pot_slope);
343         glVertex2f(vel_x - 20, pot_slope + 5);
344         glEnd();
345
346         glBegin(GL_LINE_STRIP);
347         glVertex2f(vel_x + 20, pot_slope - 5);
348         glVertex2f(vel_x + 15, pot_slope);
349         glVertex2f(vel_x + 20, pot_slope + 5);
350         glEnd();
351
352         if (pla > (105.0 / 131.0)) {
353             glBegin(GL_LINE_STRIP);
354             glVertex2f(vel_x - 24, pot_slope - 5);
355             glVertex2f(vel_x - 19, pot_slope);
356             glVertex2f(vel_x - 24, pot_slope + 5);
357             glEnd();
358
359             glBegin(GL_LINE_STRIP);
360             glVertex2f(vel_x + 24, pot_slope - 5);
361             glVertex2f(vel_x + 19, pot_slope);
362             glVertex2f(vel_x + 24, pot_slope + 5);
363             glEnd();
364         }
365     }
366
367     //**********************************************************
368     // ramp reticle
369     // OBJECT STATIC RETICLE
370     // TYPE LINE
371     // ATTRIB - ON CONDITION
372 #ifdef ENABLE_SP_FMDS
373     if (energy_worm && ilcanclaw == 1) {
374         glBegin(GL_LINE_STRIP);
375         glVertex2f(-15, -134);
376         glVertex2f(15, -134);
377         glEnd();
378
379         // OBJECT MOVING RETICLE
380         // TYPE BOX
381         // ATTRIB - ON CONDITION
382         glBegin(GL_LINE_STRIP);
383         glVertex2f(-6, -134);
384         glVertex2f(-6, t2 * SGD_RADIANS_TO_DEGREES * 4.0 - 134);
385         glVertex2f(+6, t2 * SGD_RADIANS_TO_DEGREES * 4.0 - 134);
386         glVertex2f(6, -134);
387         glEnd();
388
389         // OBJECT MOVING RETICLE
390         // TYPE DIAMOND
391         // ATTRIB - ON CONDITION
392         glBegin(GL_LINE_LOOP);
393         glVertex2f(-6, actslope * 4.0 - 134);
394         glVertex2f(0, actslope * 4.0 -134 + 3);
395         glVertex2f(6, actslope * 4.0 - 134);
396         glVertex2f(0, actslope * 4.0 -134 -3);
397         glEnd();
398     }
399 #endif
400
401     //*************************************************************
402     // OBJECT MOVING RETICLE
403     // TYPE DIAMOND
404     // ATTRIB - ALWAYS
405     // Draw the locked velocity vector.
406     if (climb_dive_marker) {
407         glBegin(GL_LINE_LOOP);
408         glVertex2f(-3.0, 0.0 + vel_y);
409         glVertex2f(0.0, 6.0 + vel_y);
410         glVertex2f(3.0, 0.0 + vel_y);
411         glVertex2f(0.0, -6.0 + vel_y);
412         glEnd();
413     }
414
415     //****************************************************************
416
417     if (climb_dive_ladder) { // CONFORMAL_HUD
418         vmin = pitch_value - (float)width_units;
419         vmax = pitch_value + (float)width_units;
420         glTranslatef(vel_x, vel_y, 0);
421
422     } else { // pitch_ladder - Default Hud
423         vmin = pitch_value - (float)width_units * 0.5f;
424         vmax = pitch_value + (float)width_units * 0.5f;
425     }
426
427     glRotatef(roll_value * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0);
428     // FRL marker not rotated - this line shifted below
429
430     if (div_units) {
431         char  TextLadder[8];
432         float label_length;
433         float label_height;
434         float left;
435         float right;
436         float bot;
437         float top;
438         float text_offset = 4.0f;
439         float zero_offset = 0.0;
440
441         if (climb_dive_ladder)
442             zero_offset = 50.0f; // horizon line is wider by this much (hard coded ??)
443         else
444             zero_offset = 10.0f;
445
446         fntFont *font = HUDtext->getFont();                     // FIXME
447         float pointsize = HUDtext->getPointSize();
448         float italic = HUDtext->getSlant();
449
450         TextList.setFont(HUDtext);
451         TextList.erase();
452         LineList.erase();
453         StippleLineList.erase();
454
455         int last = FloatToInt(vmax) + 1;
456         int i = FloatToInt(vmin);
457
458         if (!scr_hole) {
459             x_end = half_span;
460
461             for (; i<last; i++) {
462                 y = (((float)(i - pitch_value) * factor) + .5f);
463
464                 if (!(i % div_units)) {           //  At integral multiple of div
465                     sprintf(TextLadder, "%d", i);
466                     font->getBBox(TextLadder, pointsize, italic,
467                             &left, &right, &bot, &top);
468                     label_length = right - left;
469                     label_length += text_offset;
470                     label_height = (top - bot) / 2.0f;
471
472                     x_ini = -half_span;
473
474                     if (i >= 0) {
475                         // Make zero point wider on left
476                         if (i == 0)
477                             x_ini -= zero_offset;
478
479                         // Zero or above draw solid lines
480                         Line(x_ini, y, x_end, y);
481
482                         if (i == 90 && zenith == 1)
483                             drawZenith(x_ini, x_end, y);
484                     } else {
485                         // Below zero draw dashed lines.
486                         StippleLine(x_ini, y, x_end, y);
487
488                         if (i == -90 && nadir ==1)
489                             drawNadir(x_ini, x_end, y);
490                     }
491
492                     // Calculate the position of the left text and write it.
493                     Text(x_ini-label_length, y-label_height, TextLadder);
494                     Text(x_end+text_offset, y-label_height, TextLadder);
495                 }
496             }
497
498         } else { // if (scr_hole)
499             // Draw ladder with space in the middle of the lines
500             float hole = (float)((scr_hole) / 2.0f);
501
502             x_end = -half_span + hole;
503             x_ini2 = half_span - hole;
504
505             for (; i < last; i++) {
506                 if (hudladder_type == "Pitch Ladder")
507                     y = (((float)(i - pitch_value) * factor) + .5);
508                 else if (hudladder_type == "Climb/Dive Ladder")
509                     y = (((float)(i - actslope) * factor) + .5);
510
511                 if (!(i % div_units)) {  //  At integral multiple of div
512                     sprintf(TextLadder, "%d", i);
513                     font->getBBox(TextLadder, pointsize, italic,
514                             &left, &right, &bot, &top);
515                     label_length = right - left;
516                     label_length += text_offset;
517                     label_height = (top - bot) / 2.0f;
518                     // printf("l %f r %f b %f t %f\n",left, right, bot, top);
519
520                     // Start by calculating the points and drawing the
521                     // left side lines.
522                     x_ini = -half_span;
523                     x_end2 = half_span;
524
525                     if (i >= 0) {
526                         // Make zero point wider on left
527                         if (i == 0) {
528                             x_ini -= zero_offset;
529                             x_end2 += zero_offset;
530                         }
531                         //draw climb bar vertical lines
532                         if (climb_dive_ladder) {
533                             // Zero or above draw solid lines
534                             Line(x_end, y - 5.0, x_end, y);
535                             Line(x_ini2, y - 5.0, x_ini2, y);
536                         }
537                         // draw pitch / climb bar
538                         Line(x_ini, y, x_end, y);
539                         Line(x_ini2, y, x_end2, y);
540
541                         if (i == 90 && zenith == 1)
542                             drawZenith(x_ini2, x_end, y);
543
544                     } else { // i < 0
545                         // draw dive bar vertical lines
546                         if (climb_dive_ladder) {
547                             Line(x_end, y + 5.0, x_end, y);
548                             Line(x_ini2, y + 5.0, x_ini2, y);
549                         }
550
551                         // draw pitch / dive bars
552                         StippleLine(x_ini, y, x_end, y);
553                         StippleLine(x_ini2, y, x_end2, y);
554
555                         if (i == -90 && nadir == 1)
556                             drawNadir(x_ini2, x_end, y);
557                     }
558
559                     // Now calculate the location of the left side label using
560                     Text(x_ini-label_length, y - label_height, TextLadder);
561                     Text(x_end2+text_offset, y - label_height, TextLadder);
562                 }
563             }
564
565             // OBJECT LADDER MARK
566             // TYPE LINE
567             // ATTRIB - ON CONDITION
568             // draw appraoch glide slope marker
569 #ifdef ENABLE_SP_FMDS
570             if (glide_slope_marker && ihook) {
571                 Line(-half_span + 15, (glide_slope-actslope) * factor,
572                         -half_span + hole, (glide_slope - actslope) * factor);
573                 Line(half_span - 15, (glide_slope-actslope) * factor,
574                         half_span - hole, (glide_slope - actslope) * factor);
575             }
576 #endif
577         }
578         TextList.draw();
579
580         glLineWidth(0.2);
581
582         LineList.draw();
583
584         glEnable(GL_LINE_STIPPLE);
585         glLineStipple(1, 0x00FF);
586         StippleLineList.draw();
587         glDisable(GL_LINE_STIPPLE);
588     }
589     glDisable(GL_CLIP_PLANE0);
590     glDisable(GL_CLIP_PLANE1);
591     glDisable(GL_CLIP_PLANE2);
592     //  glDisable(GL_SCISSOR_TEST);
593     glPopMatrix();
594     //*************************************************************
595
596     //*************************************************************
597 #ifdef ENABLE_SP_FMDS
598     if (waypoint_marker) {
599         //waypoint marker computation
600         float fromwp_lat, towp_lat, fromwp_lon, towp_lon, dist, delx, dely, hyp, theta, brg;
601
602         fromwp_lon = get_longitude() * SGD_DEGREES_TO_RADIANS;
603         fromwp_lat = get_latitude() * SGD_DEGREES_TO_RADIANS;
604         towp_lon = get_aux2() * SGD_DEGREES_TO_RADIANS;
605         towp_lat = get_aux1() * SGD_DEGREES_TO_RADIANS;
606
607         dist = acos(sin(fromwp_lat) * sin(towp_lat) + cos(fromwp_lat)
608                 * cos(towp_lat) * cos(fabs(fromwp_lon - towp_lon)));
609         delx= towp_lat - fromwp_lat;
610         dely = towp_lon - fromwp_lon;
611         hyp = sqrt(pow(delx, 2) + pow(dely, 2));
612
613         if (hyp != 0)
614             theta = asin(dely / hyp);
615         else
616             theta = 0.0;
617
618         brg = theta * SGD_RADIANS_TO_DEGREES;
619         if (brg > 360.0)
620             brg = 0.0;
621         if (delx < 0)
622             brg = 180 - brg;
623
624         // {Brg  = asin(cos(towp_lat)*sin(fabs(fromwp_lon-towp_lon))/ sin(dist));
625         // Brg = Brg * SGD_RADIANS_TO_DEGREES; }
626
627         dist *= SGD_RADIANS_TO_DEGREES * 60.0 * 1852.0; //rad->deg->nm->m
628         // end waypoint marker computation
629
630         //*********************************************************
631         // OBJECT MOVING RETICLE
632         // TYPE ARROW
633         // waypoint marker
634         if (fabs(brg-psi) > 10.0) {
635             glPushMatrix();
636             glTranslatef(centroid.x, centroid.y, 0);
637             glTranslatef(vel_x, vel_y, 0);
638             glRotatef(brg - psi, 0.0, 0.0, -1.0);
639             glBegin(GL_LINE_LOOP);
640             glVertex2f(-2.5, 20.0);
641             glVertex2f(-2.5, 30.0);
642             glVertex2f(-5.0, 30.0);
643             glVertex2f(0.0, 35.0);
644             glVertex2f(5.0, 30.0);
645             glVertex2f(2.5, 30.0);
646             glVertex2f(2.5, 20.0);
647             glEnd();
648             glPopMatrix();
649         }
650
651         // waypoint marker on heading scale
652         if (fabs(brg-psi) < 12.0) {
653             if (hat == 0) {
654                 glBegin(GL_LINE_LOOP);
655                 glVertex2f(((brg - psi) * 60 / 25) + 320, 240.0);
656                 glVertex2f(((brg - psi) * 60 / 25) + 326, 240.0 - 4);
657                 glVertex2f(((brg - psi) * 60 / 25) + 323, 240.0 - 4);
658                 glVertex2f(((brg - psi) * 60 / 25) + 323, 240.0 - 8);
659                 glVertex2f(((brg - psi) * 60 / 25) + 317, 240.0 - 8);
660                 glVertex2f(((brg - psi) * 60 / 25) + 317, 240.0 - 4);
661                 glVertex2f(((brg - psi) * 60 / 25) + 314, 240.0 - 4);
662                 glEnd();
663
664             } else { //if hat=0
665                 float x = (brg - psi) * 60 / 25 + 320, y = 240.0, r = 5.0;
666                 float x1, y1;
667
668                 glEnable(GL_POINT_SMOOTH);
669                 glBegin(GL_POINTS);
670
671                 for (int count = 0; count <= 200; count++) {
672                     float temp = count * 3.142 * 3 / (200.0 * 2.0);
673                     float temp1 = temp - (45.0 * SGD_DEGREES_TO_RADIANS);
674                     x1 = x + r * cos(temp1);
675                     y1 = y + r * sin(temp1);
676                     glVertex2f(x1, y1);
677                 }
678
679                 glEnd();
680                 glDisable(GL_POINT_SMOOTH);
681             } //hat=0
682
683          } //brg<12
684      } // if waypoint_marker
685 #endif
686 }//draw
687
688
689 /******************************************************************/
690 //  draws the zenith symbol  for highest possible climb angle (i.e. 90 degree climb angle)
691 //
692 void HudLadder::drawZenith(float xfirst, float xlast, float yvalue)
693 {
694     float xcentre = (xfirst + xlast) / 2.0;
695     float ycentre = yvalue;
696
697     Line(xcentre - 9.0, ycentre, xcentre - 3.0, ycentre + 1.3);
698     Line(xcentre - 9.0, ycentre, xcentre - 3.0, ycentre - 1.3);
699
700     Line(xcentre + 9.0, ycentre, xcentre + 3.0, ycentre + 1.3);
701     Line(xcentre + 9.0, ycentre, xcentre + 3.0, ycentre - 1.3);
702
703     Line(xcentre, ycentre + 9.0, xcentre - 1.3, ycentre + 3.0);
704     Line(xcentre, ycentre + 9.0, xcentre + 1.3, ycentre + 3.0);
705
706     Line(xcentre - 3.9, ycentre + 3.9, xcentre - 3.0, ycentre + 1.3);
707     Line(xcentre - 3.9, ycentre + 3.9, xcentre - 1.3, ycentre + 3.0);
708
709     Line(xcentre + 3.9, ycentre + 3.9, xcentre + 1.3, ycentre+3.0);
710     Line(xcentre + 3.9, ycentre + 3.9, xcentre + 3.0, ycentre+1.3);
711
712     Line(xcentre - 3.9, ycentre - 3.9, xcentre - 3.0, ycentre-1.3);
713     Line(xcentre - 3.9, ycentre - 3.9, xcentre - 1.3, ycentre-2.6);
714
715     Line(xcentre + 3.9, ycentre - 3.9, xcentre + 3.0, ycentre-1.3);
716     Line(xcentre + 3.9, ycentre - 3.9, xcentre + 1.3, ycentre-2.6);
717
718     Line(xcentre - 1.3, ycentre - 2.6, xcentre, ycentre - 27.0);
719     Line(xcentre + 1.3, ycentre - 2.6, xcentre, ycentre - 27.0);
720 }
721
722
723 //  draws the nadir symbol  for lowest possible dive angle (i.e. 90 degree dive angle)
724 //
725 void HudLadder::drawNadir(float xfirst, float xlast, float yvalue)
726 {
727     float xcentre = (xfirst + xlast) / 2.0;
728     float ycentre = yvalue;
729
730     float r = 7.5;
731     float x1, y1, x2, y2;
732
733     // to draw a circle
734     float xcent1, xcent2, ycent1, ycent2;
735     xcent1 = xcentre + r;
736     ycent1 = ycentre;
737
738     for (int count = 1; count <= 400; count++) {
739         float temp = count * 2 * 3.142 / 400.0;
740         xcent2 = xcentre + r * cos(temp);
741         ycent2 = ycentre + r * sin(temp);
742
743         Line(xcent1, ycent1, xcent2, ycent2);
744
745         xcent1 = xcent2;
746         ycent1 = ycent2;
747     }
748
749     xcent2 = xcentre + r;
750     ycent2 = ycentre;
751
752     drawOneLine(xcent1, ycent1, xcent2, ycent2); //to connect last point to first point
753     //end circle
754
755     //to draw a line above the circle
756     Line(xcentre, ycentre + 7.5, xcentre, ycentre + 22.5);
757
758     //line in the middle of circle
759     Line(xcentre - 7.5, ycentre, xcentre + 7.5, ycentre);
760
761     float theta = asin (2.5 / 7.5);
762     float theta1 = asin(5.0 / 7.5);
763
764     x1 = xcentre + r * cos(theta);
765     y1 = ycentre + 2.5;
766     x2 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) - theta);
767     y2 = ycentre + 2.5;
768     Line(x1, y1, x2, y2);
769
770     x1 = xcentre + r * cos(theta1);
771     y1 = ycentre + 5.0;
772     x2 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) - theta1);
773     y2 = ycentre + 5.0;
774     Line(x1, y1, x2, y2);
775
776     x1 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) + theta);
777     y1 = ycentre - 2.5;
778     x2 = xcentre + r * cos((360.0 * SGD_DEGREES_TO_RADIANS) - theta);
779     y2 = ycentre - 2.5;
780     Line(x1, y1, x2, y2);
781
782     x1 = xcentre + r * cos((180.0 * SGD_DEGREES_TO_RADIANS) + theta1);
783     y1 = ycentre - 5.0;
784     x2 = xcentre + r * cos((360.0 * SGD_DEGREES_TO_RADIANS) - theta1);
785     y2 = ycentre - 5.0;
786     Line(x1, y1, x2, y2);
787 }
788
789