7 //====================== Top of HudLadder Class =======================
8 HudLadder :: HudLadder( string name,
29 float glide_slope_val,
33 dual_instr_item( x, y, width, height,
38 width_units ( (int)(span_units) ),
39 div_units ( (int)(major_div < 0? -major_div: major_div) ),
40 minor_div ( (int)(minor_div) ),
41 label_pos ( lbl_pos ),
42 scr_hole ( screen_hole ),
43 vmax ( span_units/2 ),
46 hudladder_type ( name ),
48 target_spot ( target ),
49 velocity_vector ( vel_vec ),
50 drift_marker ( drift ),
51 alpha_bracket ( alpha ),
52 energy_marker ( energy ),
53 climb_dive_marker ( climb ),
54 glide_slope_marker ( glide ),
55 glide_slope ( glide_slope_val),
56 energy_worm ( worm_energy),
57 waypoint_marker ( waypoint)
66 HudLadder :: ~HudLadder()
71 HudLadder( const HudLadder & image ) :
72 dual_instr_item ( (dual_instr_item &) image),
73 width_units ( image.width_units ),
74 div_units ( image.div_units ),
75 label_pos ( image.label_pos ),
76 scr_hole ( image.scr_hole ),
79 factor ( image.factor ),
80 hudladder_type ( image.hudladder_type),
82 target_spot ( image.target_spot),
83 velocity_vector ( image.velocity_vector),
84 drift_marker ( image.drift_marker),
85 alpha_bracket ( image.alpha_bracket),
86 energy_marker ( image.energy_marker),
87 climb_dive_marker ( image.climb_dive_marker),
88 glide_slope_marker ( image.glide_slope_marker),
89 glide_slope ( image.glide_slope),
90 energy_worm ( image.energy_worm),
91 waypoint_marker ( image.waypoint_marker)
94 HudLadder & HudLadder :: operator = ( const HudLadder & rhs )
96 if( !(this == &rhs)) {
97 (dual_instr_item &)(*this) = (dual_instr_item &)rhs;
98 width_units = rhs.width_units;
99 div_units = rhs.div_units;
100 label_pos = rhs.label_pos;
101 scr_hole = rhs.scr_hole;
105 hudladder_type = rhs.hudladder_type;
107 velocity_vector = rhs.velocity_vector;
108 drift_marker = rhs.drift_marker;
109 alpha_bracket = rhs.alpha_bracket;
110 energy_marker = rhs.energy_marker;
111 climb_dive_marker = rhs.climb_dive_marker;
112 target_spot = rhs.target_spot;
113 glide_slope_marker = rhs.glide_slope_marker;
114 glide_slope = rhs.glide_slope;
115 energy_worm = rhs.energy_worm;
116 waypoint_marker = rhs.waypoint_marker;
122 // Draws a climb ladder in the center of the HUD
125 void HudLadder :: draw( void )
132 float cosine, sine, xvvr, yvvr, Vxx = 0.0, Vyy = 0.0, Vzz = 0.0,
133 up_vel, ground_vel, actslope = 0.0;
134 float Axx = 0.0, Ayy = 0.0, Azz = 0.0, total_vel = 0.0, pot_slope, t1,
135 t2 = 0.0, psi = 0.0, alpha,pla;
136 float vel_x = 0.0, vel_y = 0.0, drift;
138 bool pitch_ladder = false;
139 bool climb_dive_ladder = false;
140 bool clip_plane = false;
142 GLdouble eqn_top[4] = {0.0,-1.0,0.0,0.0};
143 GLdouble eqn_left[4] = {-1.0,0.0,0.0,100.0};
144 GLdouble eqn_right[4] = {1.0,0.0,0.0,100.0};
146 POINT centroid = get_centroid();
147 RECT box = get_location();
149 float half_span = box.right / 2.0;
150 float roll_value = current_ch2();
152 pla = get_throttleval();
154 int lgear,wown,wowm,ilcanclaw,ihook;
155 ilcanclaw = get_iaux1();
161 float pitch_value = current_ch1() * SGD_RADIANS_TO_DEGREES;
163 if(hudladder_type=="Climb/Dive Ladder") {
164 pitch_ladder = false;
165 climb_dive_ladder = true;
169 if(hudladder_type=="Pitch Ladder") {
171 climb_dive_ladder = false;
175 //**************************************************************
177 // define (0,0) as center of screen
178 glTranslatef( centroid.x, centroid.y, 0);
180 // OBJECT STATIC RETICLE
183 // Draw the FRL spot and line
185 #define FRL_DIAMOND_SIZE 2.0
186 glBegin(GL_LINE_LOOP);
187 glVertex2f( -FRL_DIAMOND_SIZE, 0.0);
188 glVertex2f(0.0, FRL_DIAMOND_SIZE);
189 glVertex2f( FRL_DIAMOND_SIZE, 0.0);
190 glVertex2f(0.0, -FRL_DIAMOND_SIZE);
192 glBegin(GL_LINE_STRIP);
193 glVertex2f(0, FRL_DIAMOND_SIZE);
196 #undef FRL_DIAMOND_SIZE
198 // TYPE WATERLINE_MARK (W shaped _ _ )
201 //****************************************************************
203 // Draw the target spot.
205 #define CENTER_DIAMOND_SIZE 6.0
206 glBegin(GL_LINE_LOOP);
207 glVertex2f( -CENTER_DIAMOND_SIZE, 0.0);
208 glVertex2f(0.0, CENTER_DIAMOND_SIZE);
209 glVertex2f( CENTER_DIAMOND_SIZE, 0.0);
210 glVertex2f(0.0, -CENTER_DIAMOND_SIZE);
212 #undef CENTER_DIAMOND_SIZE
215 //****************************************************************
216 //velocity vector reticle - computations
217 if(velocity_vector) {
226 if (psi > 180.0) psi = psi - 360;
228 total_vel = sqrt(Vxx*Vxx + Vyy*Vyy + Vzz*Vzz);
229 ground_vel = sqrt(Vxx*Vxx + Vyy*Vyy);
232 if (ground_vel < 2.0) {
233 if (fabs(up_vel) < 2.0) {
236 actslope = (up_vel/fabs(up_vel))*90.0;
239 actslope = atan(up_vel/ground_vel)*SGD_RADIANS_TO_DEGREES;
242 xvvr = (((atan2(Vyy,Vxx)*SGD_RADIANS_TO_DEGREES)-psi)*(640.0/45.0));
243 drift = ((atan2(Vyy,Vxx)*SGD_RADIANS_TO_DEGREES)-psi);
244 yvvr = ((actslope - pitch_value)*factor);
245 vel_y = ((actslope -pitch_value) * cos(roll_value) + drift*sin(roll_value))*factor;
246 vel_x = (-(actslope -pitch_value)*sin(roll_value) + drift*cos(roll_value))*(640/45.0);
247 // printf("%f %f %f %f\n",vel_x,vel_y,drift,psi);
248 //****************************************************************
249 // OBJECT MOVING RETICLE
250 // TYPE - DRIFT MARKER
254 glBegin(GL_LINE_STRIP);
255 glVertex2f((xvvr*25/120)-6, -4);
256 glVertex2f(xvvr*25/120, 8);
257 glVertex2f((xvvr*25/120)+6, -4);
261 //****************************************************************
262 // Clipping coordinates for ladder to be input from xml file
265 glClipPlane(GL_CLIP_PLANE0,eqn_top);
266 glEnable(GL_CLIP_PLANE0);
267 glClipPlane(GL_CLIP_PLANE1,eqn_left);
268 glEnable(GL_CLIP_PLANE1);
269 glClipPlane(GL_CLIP_PLANE2,eqn_right);
270 glEnable(GL_CLIP_PLANE2);
271 // glScissor(-100,-240,200,240);
272 // glEnable(GL_SCISSOR_TEST);
274 //****************************************************************
275 // OBJECT MOVING RETICLE
276 // TYPE VELOCITY VECTOR
279 glBegin(GL_LINE_LOOP); // Use polygon to approximate a circle
280 for(count=0; count<50; count++) {
281 cosine = 6 * cos(count * 2 * SGD_PI/50.0);
282 sine = 6 * sin(count * 2 * SGD_PI/50.0);
283 glVertex2f(cosine+vel_x, sine+vel_y);
286 //velocity vector reticle orientation lines
287 glBegin(GL_LINE_STRIP);
288 glVertex2f(vel_x-12, vel_y);
289 glVertex2f(vel_x-6, vel_y);
291 glBegin(GL_LINE_STRIP);
292 glVertex2f(vel_x+12, vel_y);
293 glVertex2f(vel_x+6, vel_y);
295 glBegin(GL_LINE_STRIP);
296 glVertex2f(vel_x, vel_y+12);
297 glVertex2f(vel_x, vel_y+6);
300 // OBJECT MOVING RETICLE
302 // ATTRIB - ON CONDITION
304 // undercarriage status
305 glBegin(GL_LINE_STRIP);
306 glVertex2f(vel_x+8, vel_y);
307 glVertex2f(vel_x+8, vel_y-4);
309 // OBJECT MOVING RETICLE
311 // ATTRIB - ON CONDITION
312 glBegin(GL_LINE_STRIP);
313 glVertex2f(vel_x-8, vel_y);
314 glVertex2f(vel_x-8, vel_y-4);
316 // OBJECT MOVING RETICLE
318 // ATTRIB - ON CONDITION
319 glBegin(GL_LINE_STRIP);
320 glVertex2f(vel_x, vel_y-6);
321 glVertex2f(vel_x, vel_y-10);
325 // OBJECT MOVING RETICLE
327 // ATTRIB - ON CONDITION
329 // arrestor hook status
330 glBegin(GL_LINE_STRIP);
331 glVertex2f(vel_x-4, vel_y-8);
332 glVertex2f(vel_x, vel_y-10);
333 glVertex2f(vel_x+4, vel_y-8);
336 }//if velocity_vector
338 //***************************************************************
339 // OBJECT MOVING RETICLE
340 // TYPE - SQUARE_BRACKET
341 // ATTRIB - ON CONDITION
345 glBegin(GL_LINE_STRIP);
346 glVertex2f(vel_x-20 , vel_y-(16-alpha)*factor);
347 glVertex2f(vel_x-17, vel_y-(16-alpha)*factor);
348 glVertex2f(vel_x-17, vel_y-(14-alpha)*factor);
349 glVertex2f(vel_x-20, vel_y-(14-alpha)*factor);
351 glBegin(GL_LINE_STRIP);
352 glVertex2f(vel_x+20 , vel_y-(16-alpha)*factor);
353 glVertex2f(vel_x+17, vel_y-(16-alpha)*factor);
354 glVertex2f(vel_x+17, vel_y-(14-alpha)*factor);
355 glVertex2f(vel_x+20, vel_y-(14-alpha)*factor);
359 //printf("xvr=%f,yvr=%f,Vx=%f,Vy=%f,Vz=%f\n",xvvr,yvvr,Vx,Vy,Vz);
360 //printf("Ax=%f,Ay=%f,Az=%f\n",Ax,Ay,Az);
361 //****************************************************************
362 // OBJECT MOVING RETICLE
363 // TYPE ENERGY_MARKERS
365 //energy markers - compute potential slope
367 if (total_vel < 5.0) {
371 t1 = up_vel/total_vel;
372 t2 = asin((Vxx*Axx + Vyy*Ayy + Vzz*Azz)/(9.81*total_vel));
374 pot_slope = ((t2/3)*SGD_RADIANS_TO_DEGREES)*factor + vel_y;
375 // if (pot_slope < (vel_y - 45)) pot_slope = vel_y-45;
376 // if (pot_slope > (vel_y + 45)) pot_slope = vel_y+45;
379 glBegin(GL_LINE_STRIP);
380 glVertex2f(vel_x-20, pot_slope-5);
381 glVertex2f(vel_x-15, pot_slope);
382 glVertex2f(vel_x-20, pot_slope+5);
384 glBegin(GL_LINE_STRIP);
385 glVertex2f(vel_x+20, pot_slope-5);
386 glVertex2f(vel_x+15, pot_slope);
387 glVertex2f(vel_x+20, pot_slope+5);
389 if (pla > (105.0/131.0)) {
390 glBegin(GL_LINE_STRIP);
391 glVertex2f(vel_x-24, pot_slope-5);
392 glVertex2f(vel_x-19, pot_slope);
393 glVertex2f(vel_x-24, pot_slope+5);
395 glBegin(GL_LINE_STRIP);
396 glVertex2f(vel_x+24, pot_slope-5);
397 glVertex2f(vel_x+19, pot_slope);
398 glVertex2f(vel_x+24, pot_slope+5);
402 //**********************************************************
404 // OBJECT STATIC RETICLE
406 // ATTRIB - ON CONDITION
408 if (ilcanclaw == 1) {
409 glBegin(GL_LINE_STRIP);
410 glVertex2f(-15, -134);
411 glVertex2f(15, -134);
413 // OBJECT MOVING RETICLE
415 // ATTRIB - ON CONDITION
416 glBegin(GL_LINE_STRIP);
417 glVertex2f(-6, -134);
418 glVertex2f(-6, t2*SGD_RADIANS_TO_DEGREES*4.0 - 134);
419 glVertex2f(+6, t2*SGD_RADIANS_TO_DEGREES*4.0 - 134);
422 // OBJECT MOVING RETICLE
424 // ATTRIB - ON CONDITION
425 glBegin(GL_LINE_LOOP);
426 glVertex2f(-6, actslope*4.0 - 134);
427 glVertex2f(0, actslope*4.0 -134 +3);
428 glVertex2f(6, actslope*4.0 - 134);
429 glVertex2f(0, actslope*4.0 -134 -3);
433 //*************************************************************
434 // OBJECT MOVING RETICLE
437 // Draw the locked velocity vector.
438 if(climb_dive_marker) {
439 glBegin(GL_LINE_LOOP);
440 glVertex2f( -3.0, 0.0+vel_y);
441 glVertex2f(0.0, 6.0+vel_y);
442 glVertex2f( 3.0, 0.0+vel_y);
443 glVertex2f(0.0, -6.0+vel_y);
447 //****************************************************************
449 if(climb_dive_ladder) {// CONFORMAL_HUD
451 vmin = pitch_value - (float)width_units;
452 vmax = pitch_value + (float)width_units;
454 glTranslatef( vel_x, vel_y, 0);
458 if (pitch_ladder) {//Default Hud
460 vmin = pitch_value - (float)width_units * 0.5f;
461 vmax = pitch_value + (float)width_units * 0.5f;
465 glRotatef(roll_value * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0);
466 // FRL marker not rotated - this line shifted below
477 float text_offset = 4.0f ;
478 float zero_offset = 0.0;
480 if ( climb_dive_ladder ) {
481 zero_offset = 50.0f ;
483 if ( pitch_ladder ) {
484 zero_offset = 10.0f ;
488 fntFont *font = HUDtext->getFont();
489 float pointsize = HUDtext->getPointSize();
490 float italic = HUDtext->getSlant();
492 TextList.setFont( HUDtext );
495 StippleLineList.erase();
497 int last = FloatToInt(vmax)+1;
498 int i = FloatToInt(vmin);
502 for( ; i<last ; i++ ) {
504 y = (((float)(i - pitch_value) * factor) + .5f);
505 if( !(i % div_units )) { // At integral multiple of div
507 sprintf( TextLadder, "%d", i );
508 font->getBBox ( TextLadder, pointsize, italic,
509 &left, &right, &bot, &top ) ;
510 label_length = right - left;
511 label_length += text_offset;
512 label_height = (top - bot)/2.0f;
517 // Make zero point wider on left
519 x_ini -= zero_offset;
520 // Zero or above draw solid lines
521 Line(x_ini, y, x_end, y);
523 // Below zero draw dashed lines.
524 StippleLine(x_ini, y, x_end, y);
527 // Calculate the position of the left text and write it.
528 Text( x_ini-label_length, y-label_height, TextLadder );
529 Text( x_end+text_offset, y-label_height, TextLadder );
533 else // if(scr_hole )
534 { // Draw ladder with space in the middle of the lines
535 float hole = (float)((scr_hole)/2.0f);
537 x_end = -half_span + hole;
538 x_ini2= half_span - hole;
539 for( ; i<last ; i++ ) {
541 if(hudladder_type=="Pitch Ladder")
542 y = (((float)(i - pitch_value) * factor) + .5);
544 if(hudladder_type=="Climb/Dive Ladder")
545 y = (((float)(i - actslope) * factor) + .5);
547 if( !(i % div_units )) { // At integral multiple of div
549 sprintf( TextLadder, "%d", i );
550 font->getBBox ( TextLadder, pointsize, italic,
551 &left, &right, &bot, &top ) ;
552 label_length = right - left;
553 label_length += text_offset;
554 label_height = (top - bot)/2.0f;
555 // printf("l %f r %f b %f t %f\n",left, right, bot, top );
557 // Start by calculating the points and drawing the
563 // Make zero point wider on left
565 x_ini -= zero_offset;
566 x_end2 +=zero_offset;
568 if(climb_dive_ladder){
569 // Zero or above draw solid lines
570 Line(x_end, y-5.0, x_end, y);
571 Line(x_ini2, y-5.0, x_ini2, y);
575 Line(x_ini, y, x_end, y);
576 Line(x_ini2, y, x_end2, y);
579 // Below zero draw dashed lines.
580 if(climb_dive_ladder) {
581 Line(x_end, y+5.0, x_end, y);
582 Line(x_ini2, y+5.0, x_ini2, y);
584 StippleLine(x_ini, y, x_end, y);
585 StippleLine(x_ini2, y, x_end2, y);
588 // Now calculate the location of the left side label using
589 Text( x_ini-label_length, y-label_height, TextLadder );
590 Text (x_end2+text_offset, y-label_height, TextLadder );
595 // OBJECT LADDER MARK
597 // ATTRIB - ON CONDITION
598 // draw appraoch glide slope marker
599 if (glide_slope_marker) {
601 Line(-half_span+15, (glide_slope-actslope)*factor, -half_span + hole, (glide_slope-actslope)*factor);
602 Line(half_span-15, (glide_slope-actslope)*factor, half_span - hole, (glide_slope-actslope)*factor);
604 }// if glide_slope_marker
612 glEnable(GL_LINE_STIPPLE);
613 glLineStipple( 1, 0x00FF );
614 StippleLineList.draw( );
615 glDisable(GL_LINE_STIPPLE);
617 glDisable(GL_CLIP_PLANE0);
618 glDisable(GL_CLIP_PLANE1);
619 glDisable(GL_CLIP_PLANE2);
620 // glDisable(GL_SCISSOR_TEST);
622 //*************************************************************
623 //*************************************************************
624 if(waypoint_marker) {
625 //waypoint marker computation
626 float fromwp_lat,towp_lat,fromwp_lon,towp_lon,dist,delx,dely,hyp,theta,brg;
628 fromwp_lon = get_longitude()*SGD_DEGREES_TO_RADIANS;
629 fromwp_lat = get_latitude()*SGD_DEGREES_TO_RADIANS;
630 towp_lon = get_aux5()*SGD_DEGREES_TO_RADIANS;
631 towp_lat = get_aux6()*SGD_DEGREES_TO_RADIANS;
633 dist = acos(sin(fromwp_lat)*sin(towp_lat)+cos(fromwp_lat)*cos(towp_lat)*cos(fabs(fromwp_lon-towp_lon)));
634 delx= towp_lat - fromwp_lat;
635 dely = towp_lon - fromwp_lon;
636 hyp = sqrt(pow(delx,2)+pow(dely,2));
638 theta = asin(dely/hyp);
642 brg = theta*SGD_RADIANS_TO_DEGREES;
643 if (brg > 360.0) brg = 0.0;
644 if (delx < 0) brg = 180 - brg;
646 // {Brg = asin(cos(towp_lat)*sin(fabs(fromwp_lon-towp_lon))/ sin(dist));
647 // Brg = Brg * SGD_RADIANS_TO_DEGREES; }
648 dist = dist*SGD_RADIANS_TO_DEGREES * 60.0*1852.0; //rad->deg->nm->m
649 // end waypoint marker computation
650 //*********************************************************
651 // OBJECT MOVING RETICLE
654 if (fabs(brg-psi) > 10.0) {
656 glTranslatef( centroid.x, centroid.y, 0);
657 glTranslatef( vel_x, vel_y, 0);
658 glRotatef(brg - psi,0.0,0.0,-1.0);
659 glBegin(GL_LINE_LOOP);
660 glVertex2f(-2.5,20.0);
661 glVertex2f(-2.5,30.0);
662 glVertex2f(-5.0,30.0);
663 glVertex2f(0.0,35.0);
664 glVertex2f(5.0,30.0);
665 glVertex2f(2.5,30.0);
666 glVertex2f(2.5,20.0);
670 // waypoint marker on heading scale
671 if (fabs(brg-psi) < 12.0) {
672 glBegin(GL_LINE_LOOP);
673 glVertex2f(((brg-psi)*60/25)+320,240.0);
674 glVertex2f(((brg-psi)*60/25)+326,240.0-4);
675 glVertex2f(((brg-psi)*60/25)+323,240.0-4);
676 glVertex2f(((brg-psi)*60/25)+323,240.0-8);
677 glVertex2f(((brg-psi)*60/25)+317,240.0-8);
678 glVertex2f(((brg-psi)*60/25)+317,240.0-4);
679 glVertex2f(((brg-psi)*60/25)+314,240.0-4);
682 //*************************************************************
683 }// if waypoint_marker