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