HUD.nas 112 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858
  1. print("*** LOADING HUD.nas ... ***");
  2. ################################################################################
  3. #
  4. # m2005-5's HUD AI/MP SETTINGS
  5. #
  6. ################################################################################
  7. #panel with revi:
  8. # <x-m> -3.653 </x-m>
  9. # <y-m> 0.000 </y-m>
  10. # <z-m> -0.297 </z-m>
  11. # <pitch-deg> -14 </pitch-deg>
  12. #revi:
  13. # <x-m> 0.456 </x-m>
  14. # <y-m> 0.000 </y-m>
  15. # <z-m> 0.159 </z-m>
  16. var roundabout = func(x) {
  17. var y = x - int(x);
  18. return y < 0.5 ? int(x) : 1 + int(x) ;
  19. };
  20. var target_marker = func()
  21. {
  22. # draw hud markers on top of each AI/MP target
  23. #SGPropertyNode * models = globals->get_props()->getNode("/ai/models", true);
  24. #for(int i = 0 ; i < models->nChildren() ; i += 1)
  25. #{
  26. # @TODO: hardball : I don't understand this line :
  27. # SGPropertyNode * chld = models->getChild(i);
  28. #string name;
  29. #name = chld->getName();
  30. #if(name == "aircraft" || name == "multiplayer" || type == "tanker" || type == "carrier")
  31. #{
  32. # string callsign = chld->getStringValue("callsign");
  33. #if(callsign != "")
  34. #{
  35. # float h_deg = chld->getFloatValue("radar/h-offset");
  36. # float v_deg = chld->getFloatValue("radar/v-offset");
  37. # float pos_x = (h_deg * cos(roll_value) - v_deg * sin(roll_value)) * _compression;
  38. #float pos_y = (v_deg * cos(roll_value) + h_deg * sin(roll_value)) * _compression;
  39. # draw_circle(pos_x, pos_y, 8);
  40. # }
  41. #}
  42. #}
  43. }
  44. var x_view = props.globals.getNode("sim/current-view/x-offset-m");
  45. var y_view = props.globals.getNode("sim/current-view/y-offset-m");
  46. var z_view = props.globals.getNode("sim/current-view/z-offset-m");
  47. var Hud_Position = [-0.0005,0.0298,-3.16320];
  48. var PilotCurrentView = [x_view.getValue(),y_view.getValue(),z_view.getValue()];
  49. var pow2 = func(x) { return x * x; };
  50. var vec_length = func(x, y,z=0) { return math.sqrt(pow2(x) + pow2(y)+pow2(z)); };
  51. #Nodes values variables
  52. var mydeviation = 0;
  53. var myelevation = 0;
  54. var displayIt = 0;
  55. # var target_callsign = "";
  56. # var target_altitude = 0;
  57. # var target_closureRate = 0;
  58. # var target_heading_deg = 0;
  59. # var target_Distance = 0;
  60. # var raw_list = [];
  61. #verre2
  62. # ==============================================================================
  63. # Head up display
  64. # ==============================================================================
  65. var pow2 = func(x) { return x * x; };
  66. var vec_length = func(x, y) { return math.sqrt(pow2(x) + pow2(y)); };
  67. var round0 = func(x) { return math.abs(x) > 0.01 ? x : 0; };
  68. var clamp = func(x, min, max) { return x < min ? min : (x > max ? max : x); }
  69. #canvas.
  70. #the canvas is wider than the actual hud : so display start at 16,7% of the hud and end at 84,3% (100%-16.7%)
  71. #vertical is 100%
  72. #the HUD is slanted. Angle : 40%
  73. #Canvs start upper right
  74. #x is positive rightwards. y is positive downwards
  75. #480,480 --> (140,-150) - (150,200)
  76. #Canvas coordinates :
  77. #X: 80 to 400
  78. #Y: 27.36 to 456.89
  79. #HUD Position : x,y,z
  80. #left lower corner (-0.07606, -0.07327, -0.03237)
  81. #right upper corner (0.05357, 0.07327, 0.11536)
  82. #Center HUD : (-0.12963,0,0.08299)
  83. #OFFSET1 panel.xml :<offsets><x-m> 0.456 </x-m> <y-m> 0.000 </y-m><z-m> 0.159 </z-m></offsets>
  84. #OFFSET2 interior.xml <offsets><x-m> -3.653 </x-m> <y-m> 0.000 </y-m> <z-m> -0.297 </z-m> <pitch-deg> -14 </pitch-deg> </offsets>
  85. #TO do = update distance to HUD in fonction of the position on it : if vertical on 2D HUD is high, distance should be lower.
  86. #find a trigonometric way to calculate the y position (2D HUD) as the real hud have around 45° of inclinaison.
  87. #Make it happen for all non null radar properies
  88. #Make null properties hidded
  89. #var centerHUDx = (-0.07606 + 0.05357)/2;
  90. #var centerHUDy = (-0.07327 +0.07327)/2;
  91. #var centerHUDz = (-0.03237 +0.11536)/2;
  92. #centerHUDx = centerHUDx+0.456-3.653;
  93. #centerHUDy = centerHUDy;
  94. #centerHUDz = centerHUDz+0.159-0.297;
  95. #centerHUDz = 0.040;
  96. #leftbottom: -3.20962,-0.067,-0.15438
  97. #righttop: -3.20962, 0.067,-0.02038
  98. centerHUDx = -3.20962;
  99. centerHUDy = 0;
  100. centerHUDz = (-0.15438 + -0.02038)/2;
  101. var heightMeters = 0.067-(-0.067);
  102. var wideMeters = math.abs(-0.02038 - (-0.15438));
  103. #Pilot position:
  104. #Pilotz = getprop("sim/view[0]/config/y-offset-m");
  105. #Pilotx = getprop("sim/view[0]/config/z-offset-m");
  106. #Piloty = getprop("sim/view[0]/config/x-offset-m");
  107. #var raw_list = props.globals.getNode("instrumentation/radar2/targets").getChildren();
  108. #print("Size:" ~ size(raw_list));
  109. # var MaxTarget = 30;
  110. #center of the hud
  111. #X = 420 * 2
  112. #Y = 1024 => 512 * 2
  113. var HUD = {
  114. canvas_settings: {
  115. "name": "HUD",
  116. "size": [1024,1024],#<-- size of the texture
  117. "view": [1024,1024], #<- Size of the coordinate systems (the bigger the sharpener)
  118. "mipmapping": 0
  119. },
  120. new: func(placement)
  121. {
  122. var m = {
  123. parents: [HUD],
  124. canvas: canvas.new(HUD.canvas_settings)
  125. };
  126. HudMath.init([-3.3935,-0.067,0.12032], [-3.3935,0.067,-0.041679], [1024,1024], [0,1.0], [0.8265,0.0], 0);
  127. #HudMath.init([-3.26163,-0.067,0.099216], [-3.26163,0.067,-0.062785], [1024,1024], [0,1.0], [0.8265,0.0], 0);
  128. #HudMath.init([-3.22012,-0.07327,0.101839], [-3.32073,0.07327,-0.093358], [1024,1024], [0.166803,1.0], [0.834003,0.0], 0); wrong HUD
  129. m.sy = 1024/2;
  130. m.sx = 1024/2;
  131. m.viewPlacement = 480;
  132. m.min = -m.viewPlacement * 0.846;
  133. m.max = m.viewPlacement * 0.846;
  134. m.MaxX = 420; #the canvas is 420 *2;
  135. m.MaxY = 512; #the canvas is 420 *2;
  136. m.red = 0.3;
  137. m.green = 1.0;
  138. m.blue = 0.3;
  139. m.MaxTarget = 30;
  140. #m.myGreen = [0.3,1.0,0.3,1];
  141. m.myGreen = [0,1,0,1];
  142. # .setColor(m.myGreen)
  143. m.canvas.addPlacement(placement);
  144. #m.canvas.setColorBackground(red, green, blue, 0.0);
  145. #m.canvas.setColorBackground(0.36, 1, 0.3, 0.02);
  146. m.canvas.setColorBackground(m.red, m.green, m.blue, 0.00);
  147. #.set("stroke", "rgba(0,255,0,0.9)");
  148. #.setColor(0.3,1,0.3)
  149. m.root =
  150. m.canvas.createGroup()
  151. .setTranslation(HudMath.getCenterOrigin())
  152. .set("font", "LiberationFonts/LiberationMono-Regular.ttf")
  153. .setDouble("character-size", 18)
  154. .setDouble("character-aspect-ration", 0.9);
  155. # m.root.setColor(m.red,m.green,m.blue,1);
  156. m.text =
  157. m.root.createChild("group");
  158. m.Fire_GBU =
  159. m.text.createChild("text")
  160. .setAlignment("center-center")
  161. .setTranslation(0, 70)
  162. .setColor(m.myGreen)
  163. .setDouble("character-size", 42);
  164. #fpv
  165. m.fpv = m.root.createChild("path")
  166. .setColor(m.myGreen)
  167. .moveTo(15, 0)
  168. .horiz(40)
  169. .moveTo(15, 0)
  170. .arcSmallCW(15,15, 0, -30, 0)
  171. .arcSmallCW(15,15, 0, 30, 0)
  172. .moveTo(-15, 0)
  173. .horiz(-40)
  174. .moveTo(0, -15)
  175. .vert(-15)
  176. .setStrokeLineWidth(4);
  177. m.AutopilotStar = m.root.createChild("text")
  178. .setColor(m.myGreen)
  179. .setTranslation(150,0)
  180. .setDouble("character-size", 50)
  181. .setAlignment("center-center")
  182. .setText("*");
  183. #Little House pointing Waypoint
  184. m.HouseSize = 4;
  185. m.HeadingHouse = m.root.createChild("path")
  186. .setColor(m.myGreen)
  187. .setStrokeLineWidth(5)
  188. .moveTo(-20,0)
  189. .vert(-30)
  190. .lineTo(0,-50)
  191. .lineTo(20,-30)
  192. .vert(30);
  193. #Chevrons Acceleration Vector (AV)
  194. m.chevronFactor = 50;
  195. m.chevronGroup = m.root.createChild("group");
  196. m.chevronGroupAB = m.chevronGroup.createChild("group");
  197. m.LeftChevron = m.chevronGroup.createChild("text")
  198. .setColor(m.myGreen)
  199. .setTranslation(-150,0)
  200. .setDouble("character-size", 60)
  201. .setAlignment("center-center")
  202. .setText(">");
  203. m.LeftChevronAB = m.chevronGroupAB.createChild("text")
  204. .setColor(m.myGreen)
  205. .setTranslation(-180,0)
  206. .setDouble("character-size", 60)
  207. .setAlignment("center-center")
  208. .setText(">");
  209. m.RightChevron = m.chevronGroup.createChild("text")
  210. .setColor(m.myGreen)
  211. .setTranslation(150,0)
  212. .setDouble("character-size", 60)
  213. .setAlignment("center-center")
  214. .setText("<");
  215. m.RightChevronAB = m.chevronGroupAB.createChild("text")
  216. .setColor(m.myGreen)
  217. .setTranslation(180,0)
  218. .setDouble("character-size", 60)
  219. .setAlignment("center-center")
  220. .setText("<");
  221. #bore cross
  222. m.boreCross = m.root.createChild("path")
  223. .setColor(m.myGreen)
  224. .moveTo(-20, 0)
  225. .horiz(40)
  226. .moveTo(0, -20)
  227. .vert(40)
  228. .setStrokeLineWidth(4);
  229. #WP cross
  230. m.WaypointCross = m.root.createChild("path")
  231. .setColor(m.myGreen)
  232. .moveTo(-20, 0)
  233. .horiz(12)
  234. .moveTo(8, 0)
  235. .horiz(12)
  236. .moveTo(0, -20)
  237. .vert(12)
  238. .moveTo(0, 8)
  239. .vert(12)
  240. .setStrokeLineWidth(4);
  241. # Horizon groups
  242. m.horizon_group = m.root.createChild("group");
  243. m.h_rot = m.horizon_group.createTransform();
  244. m.horizon_sub_group = m.horizon_group.createChild("group");
  245. # Horizon and pitch lines
  246. m.horizon_sub_group.createChild("path")
  247. .setColor(m.myGreen)
  248. .moveTo(-700, 0)
  249. .horiz(1400)
  250. .setStrokeLineWidth(4);
  251. #ILS stuff
  252. m.ILS_Scale_dependant = m.horizon_sub_group.createChild("group");
  253. #Runway on the HorizonLine
  254. m.RunwayOnTheHorizonLine = m.ILS_Scale_dependant.createChild("path")
  255. .setColor(m.myGreen)
  256. .move(0,0)
  257. .vert(-30)
  258. .setStrokeLineWidth(6);
  259. m.ILS_localizer_deviation = m.ILS_Scale_dependant.createChild("path")
  260. .setColor(m.myGreen)
  261. .move(0,0)
  262. .vert(1500)
  263. .setStrokeDashArray([30, 30, 30, 30, 30])
  264. #.setCenter(0.0)
  265. .setStrokeLineWidth(5);
  266. m.ILS_localizer_deviation.setCenter(0,0);
  267. #Part of the ILS not dependant of the SCALE
  268. m.ILS_Scale_Independant = m.root.createChild("group");
  269. m.ILS_Square = m.ILS_Scale_Independant.createChild("path")
  270. .setColor(m.myGreen)
  271. .move(-25,-25)
  272. .vert(50)
  273. .horiz(50)
  274. .vert(-50)
  275. .horiz(-50)
  276. .setStrokeLineWidth(6);
  277. #Landing Brackets
  278. m.brackets = m.ILS_Scale_Independant.createChild("group");
  279. m.LeftBracket = m.brackets.createChild("text")
  280. .setColor(m.myGreen)
  281. .setTranslation(-140,0)
  282. .setDouble("character-size", 60)
  283. .setAlignment("center-center")
  284. .setText("]");
  285. m.RightBracket = m.brackets.createChild("text")
  286. .setColor(m.myGreen)
  287. .setTranslation(140,0)
  288. .setDouble("character-size", 60)
  289. .setAlignment("center-center")
  290. .setText("[");
  291. m.ladderScale = 7.5;#7.5
  292. m.maxladderspan = 200;
  293. m.LadderGroup = m.horizon_sub_group.createChild("group");
  294. for (var myladder = 5;myladder <= 90;myladder+=5)
  295. {
  296. if (myladder/10 == int(myladder/10)){
  297. #Text bellow 0 left
  298. m.LadderGroup.createChild("text")
  299. .setColor(m.myGreen)
  300. .setAlignment("right-center")
  301. .setTranslation(-m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  302. .setDouble("character-size", 30)
  303. .setText(myladder);
  304. #Text bellow 0 left
  305. m.LadderGroup.createChild("text")
  306. .setColor(m.myGreen)
  307. .setAlignment("left-center")
  308. .setTranslation(m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  309. .setDouble("character-size", 30)
  310. .setText(myladder);
  311. #Text above 0 left
  312. m.LadderGroup.createChild("text")
  313. .setColor(m.myGreen)
  314. .setAlignment("right-center")
  315. .setTranslation(-m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*-myladder)
  316. .setDouble("character-size", 30)
  317. .setText(myladder);
  318. #Text above 0 right
  319. m.LadderGroup.createChild("text")
  320. .setColor(m.myGreen)
  321. .setAlignment("left-center")
  322. .setTranslation(m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*-myladder)
  323. .setDouble("character-size", 30)
  324. .setText(myladder);
  325. }
  326. # ============= BELLOW 0 ===================
  327. #half line bellow 0 (left part) ------------------
  328. m.LadderGroup.createChild("path")
  329. .setColor(m.myGreen)
  330. .moveTo(-m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  331. .vert(-m.maxladderspan/15)
  332. .setStrokeLineWidth(4);
  333. m.LadderGroup.createChild("path")
  334. .setColor(m.myGreen)
  335. .moveTo(-m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  336. .horiz(m.maxladderspan*2/15)
  337. .setStrokeLineWidth(4);
  338. m.LadderGroup.createChild("path")
  339. .setColor(m.myGreen)
  340. .moveTo(-abs(m.maxladderspan - m.maxladderspan*2/15*2), HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  341. .horiz(m.maxladderspan*2/15)
  342. .setStrokeLineWidth(4);
  343. m.LadderGroup.createChild("path")
  344. .setColor(m.myGreen)
  345. .moveTo(-abs(m.maxladderspan - m.maxladderspan*2/15*4), HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  346. .horiz(m.maxladderspan*2/15)
  347. .setStrokeLineWidth(4);
  348. #half line (rigt part) ------------------
  349. m.LadderGroup.createChild("path")
  350. .setColor(m.myGreen)
  351. .moveTo(m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  352. .vert(-m.maxladderspan/15)
  353. .setStrokeLineWidth(4);
  354. m.LadderGroup.createChild("path")
  355. .setColor(m.myGreen)
  356. .moveTo(m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  357. .horiz(-m.maxladderspan*2/15)
  358. .setStrokeLineWidth(4);
  359. m.LadderGroup.createChild("path")
  360. .setColor(m.myGreen)
  361. .moveTo(abs(m.maxladderspan - m.maxladderspan*2/15*2), HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  362. .horiz(-m.maxladderspan*2/15)
  363. .setStrokeLineWidth(4);
  364. m.LadderGroup.createChild("path")
  365. .setColor(m.myGreen)
  366. .moveTo(abs(m.maxladderspan - m.maxladderspan*2/15*4), HudMath.getPixelPerDegreeAvg(m.ladderScale)*myladder)
  367. .horiz(-m.maxladderspan*2/15)
  368. .setStrokeLineWidth(4);
  369. # ============= ABOVE 0 ===================
  370. m.LadderGroup.createChild("path")
  371. .setColor(m.myGreen)
  372. .moveTo(-m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*-myladder)
  373. .vert(m.maxladderspan/15)
  374. .setStrokeLineWidth(4);
  375. m.LadderGroup.createChild("path")
  376. .setColor(m.myGreen)
  377. .moveTo(-m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*-myladder)
  378. .horiz(m.maxladderspan/3*2)
  379. .setStrokeLineWidth(4);
  380. #half line (rigt part) ------------------
  381. m.LadderGroup.createChild("path")
  382. .setColor(m.myGreen)
  383. .moveTo(m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*-myladder)
  384. .horiz(-m.maxladderspan/3*2)
  385. .setStrokeLineWidth(4);
  386. m.LadderGroup.createChild("path")
  387. .setColor(m.myGreen)
  388. .moveTo(m.maxladderspan, HudMath.getPixelPerDegreeAvg(m.ladderScale)*-myladder)
  389. .vert(m.maxladderspan/15)
  390. .setStrokeLineWidth(4);
  391. }
  392. #This is the inverted T that is present in at -13 and putting this line on the horizon will keep the aircraft at 13 which is the perfect angle to take off and to land
  393. m.InvertedT = m.root.createChild("path")
  394. .setColor(m.myGreen)
  395. .moveTo(-m.maxladderspan/2, 0)
  396. .horiz(m.maxladderspan)
  397. .moveTo(0, 0)
  398. .vert(-m.maxladderspan/15*2)
  399. .setStrokeLineWidth(6);
  400. # m.InvertedT = m.root.createChild("path")
  401. # .moveTo(-m.maxladderspan/2, HudMath.getCenterPosFromDegs(0,-13)[1])
  402. # .horiz(m.maxladderspan)
  403. # .moveTo(0, HudMath.getCenterPosFromDegs(0,-13)[1])
  404. # .vert(-m.maxladderspan/15*2)
  405. # .setStrokeLineWidth(4);
  406. #m.horizon_sub_group.createChild("path")
  407. #.moveTo(-100, HudMath.getPixelPerDegreeAvg(5)*-5)
  408. #.horiz(200)
  409. #.setStrokeLineWidth(4);
  410. # m.horizon_sub_group.createChild("path")
  411. # .moveTo(-100, HudMath.getPixelPerDegreeAvg(10)*10)
  412. # .horiz(200)
  413. # .setStrokeLineWidth(4);
  414. # m.horizon_sub_group.createChild("path")
  415. # .moveTo(-100, HudMath.getPixelPerDegreeAvg(10)*-10)
  416. # .horiz(200)
  417. # .setStrokeLineWidth(4);
  418. # m.horizon_sub_group.createChild("path")
  419. # .moveTo(-100, HudMath.getPixelPerDegreeAvg(15)*15)
  420. # .horiz(200)
  421. # .setStrokeLineWidth(4);
  422. # m.horizon_sub_group.createChild("path")
  423. # .moveTo(-100, HudMath.getPixelPerDegreeAvg(15)*-15)
  424. # .horiz(200)
  425. # .setStrokeLineWidth(4);
  426. m.headScaleTickSpacing = 45;
  427. m.headScaleVerticalPlace = -450;
  428. m.headingStuff = m.root.createChild("group");
  429. m.headingScaleGroup = m.headingStuff.createChild("group");
  430. m.headingStuff.set("clip-frame", canvas.Element.LOCAL);
  431. m.headingStuff.set("clip", "rect(-500px, 150px, -400px, -150px)");# top,right,bottom,left
  432. m.head_scale = m.headingScaleGroup.createChild("path")
  433. .setColor(m.myGreen)
  434. .moveTo(-m.headScaleTickSpacing*2, m.headScaleVerticalPlace)
  435. .vert(-15)
  436. .moveTo(0, m.headScaleVerticalPlace)
  437. .vert(-15)
  438. .moveTo(m.headScaleTickSpacing*2, m.headScaleVerticalPlace)
  439. .vert(-15)
  440. .moveTo(m.headScaleTickSpacing*4, m.headScaleVerticalPlace)
  441. .vert(-15)
  442. .moveTo(-m.headScaleTickSpacing, m.headScaleVerticalPlace)
  443. .vert(-5)
  444. .moveTo(m.headScaleTickSpacing, m.headScaleVerticalPlace)
  445. .vert(-5)
  446. .moveTo(-m.headScaleTickSpacing*3, m.headScaleVerticalPlace)
  447. .vert(-5)
  448. .moveTo(m.headScaleTickSpacing*3, m.headScaleVerticalPlace)
  449. .vert(-5)
  450. .setStrokeLineWidth(5)
  451. .show();
  452. #Heading middle number on horizon line
  453. me.hdgMH = m.headingScaleGroup.createChild("text")
  454. .setColor(m.myGreen)
  455. .setTranslation(0,m.headScaleVerticalPlace -15)
  456. .setDouble("character-size", 30)
  457. .setAlignment("center-bottom")
  458. .setText("0");
  459. # # Heading left number on horizon line
  460. me.hdgLH = m.headingScaleGroup.createChild("text")
  461. .setColor(m.myGreen)
  462. .setTranslation(-m.headScaleTickSpacing*2,m.headScaleVerticalPlace -15)
  463. .setDouble("character-size", 30)
  464. .setAlignment("center-bottom")
  465. .setText("350");
  466. # # Heading right number on horizon line
  467. me.hdgRH = m.headingScaleGroup.createChild("text")
  468. .setColor(m.myGreen)
  469. .setTranslation(m.headScaleTickSpacing*2,m.headScaleVerticalPlace -15)
  470. .setDouble("character-size", 30)
  471. .setAlignment("center-bottom")
  472. .setText("10");
  473. # Heading right right number on horizon line
  474. me.hdgRRH = m.headingScaleGroup.createChild("text")
  475. .setColor(m.myGreen)
  476. .setTranslation(m.headScaleTickSpacing*4,m.headScaleVerticalPlace -15)
  477. .setDouble("character-size", 30)
  478. .setAlignment("center-bottom")
  479. .setText("20");
  480. #Point the The Selected Route. it's at the middle of the HUD
  481. m.TriangleSize = 4;
  482. m.head_scale_route_pointer = m.headingStuff.createChild("path")
  483. .setColor(m.myGreen)
  484. .setStrokeLineWidth(3)
  485. .moveTo(0, m.headScaleVerticalPlace)
  486. .lineTo(m.TriangleSize*-5/2, (m.headScaleVerticalPlace)+(m.TriangleSize*5))
  487. .lineTo(m.TriangleSize*5/2,(m.headScaleVerticalPlace)+(m.TriangleSize*5))
  488. .lineTo(0, m.headScaleVerticalPlace);
  489. #a line representthe middle and the actual heading
  490. m.heading_pointer_line = m.headingStuff.createChild("path")
  491. .setColor(m.myGreen)
  492. .setStrokeLineWidth(4)
  493. .moveTo(0, m.headScaleVerticalPlace + 2)
  494. .vert(20);
  495. m.speedAltGroup = m.root.createChild("group");
  496. # Heading right right number on horizon line
  497. me.Speed = m.speedAltGroup.createChild("text")
  498. .setColor(m.myGreen)
  499. .setTranslation(- m.maxladderspan,m.headScaleVerticalPlace)
  500. .setDouble("character-size", 50)
  501. .setAlignment("right-bottom")
  502. .setText("0");
  503. me.Speed_Mach = m.speedAltGroup.createChild("text")
  504. .setColor(m.myGreen)
  505. .setTranslation(- m.maxladderspan,m.headScaleVerticalPlace+25)
  506. .setDouble("character-size", 30)
  507. .setAlignment("right-bottom")
  508. .setText("0");
  509. # Heading right right number on horizon line
  510. me.hundred_feet_Alt = m.speedAltGroup.createChild("text")
  511. .setTranslation(m.maxladderspan + 60 ,m.headScaleVerticalPlace)
  512. .setDouble("character-size", 50)
  513. .setAlignment("right-bottom")
  514. .setText("0");
  515. # Heading right right number on horizon line
  516. me.feet_Alt = m.speedAltGroup.createChild("text")
  517. .setColor(m.myGreen)
  518. .setTranslation(m.maxladderspan + 60,m.headScaleVerticalPlace)
  519. .setDouble("character-size", 30)
  520. .setAlignment("left-bottom")
  521. .setText("00");
  522. # Heading right right number on horizon line
  523. me.groundAlt = m.speedAltGroup.createChild("text")
  524. .setColor(m.myGreen)
  525. .setTranslation(m.maxladderspan + 95,m.headScaleVerticalPlace+25)
  526. .setDouble("character-size", 30)
  527. .setAlignment("right-bottom")
  528. .setText("*****");
  529. # Heading right right number on horizon line
  530. me.theH = m.speedAltGroup.createChild("text")
  531. .setColor(m.myGreen)
  532. .setTranslation(m.maxladderspan + 100,m.headScaleVerticalPlace+25)
  533. .setDouble("character-size", 30)
  534. .setAlignment("left-bottom")
  535. .setText("H");
  536. m.alphaGroup = m.root.createChild("group");
  537. #alpha
  538. m.alpha = m.alphaGroup.createChild("text")
  539. .setColor(m.myGreen)
  540. .setTranslation(- m.maxladderspan-70,m.headScaleVerticalPlace+50)
  541. .setDouble("character-size", 40)
  542. .setAlignment("right-center")
  543. .setText("α");
  544. #aoa
  545. m.aoa = m.alphaGroup.createChild("text")
  546. .setColor(m.myGreen)
  547. .setTranslation(- m.maxladderspan-50,m.headScaleVerticalPlace+50)
  548. .setDouble("character-size", 30)
  549. .setAlignment("left-center")
  550. .setText("0.0");
  551. m.alphaGloadGroup = m.root.createChild("group");
  552. m.gload_Text = m.alphaGloadGroup.createChild("text")
  553. .setColor(m.myGreen)
  554. .setTranslation(- m.maxladderspan-50,-120)
  555. .setDouble("character-size", 35)
  556. .setAlignment("right-center")
  557. .setText("0.0");
  558. m.alpha_Text = m.alphaGloadGroup.createChild("text")
  559. .setColor(m.myGreen)
  560. .setTranslation(- m.maxladderspan-50,-90)
  561. .setDouble("character-size", 35)
  562. .setAlignment("right-center")
  563. .setText("0.0");
  564. m.alphaGloadGroup.hide();
  565. m.loads_Type_text = m.root.createChild("text")
  566. .setColor(m.myGreen)
  567. .setTranslation(- m.maxladderspan-90,-150)
  568. .setDouble("character-size", 35)
  569. .setAlignment("right-center")
  570. .setText("0.0");
  571. m.loads_Type_text.hide();
  572. # Bullet count when CAN is selected
  573. m.bullet_CountGroup = m.root.createChild("group");
  574. m.Left_bullet_Count = m.bullet_CountGroup.createChild("text")
  575. .setColor(m.myGreen)
  576. .setTranslation(-m.maxladderspan+60,100)
  577. .setDouble("character-size", 35)
  578. .setFont("LiberationFonts/LiberationMono-Bold.ttf")
  579. .setAlignment("center-center")
  580. .setText("0.0");
  581. m.Right_bullet_Count = m.bullet_CountGroup.createChild("text")
  582. .setColor(m.myGreen)
  583. .setTranslation(m.maxladderspan-60,100)
  584. .setDouble("character-size", 35)
  585. .setFont("LiberationFonts/LiberationMono-Bold.ttf")
  586. .setAlignment("center-center")
  587. .setText("0.0");
  588. m.bullet_CountGroup.hide();
  589. # Pylon selection letters
  590. m.pylons_Group = m.root.createChild("group");
  591. m.Left_pylons = m.pylons_Group.createChild("text")
  592. .setColor(m.myGreen)
  593. .setTranslation(-m.maxladderspan+60,100)
  594. .setDouble("character-size", 35)
  595. .setFont("LiberationFonts/LiberationMono-Bold.ttf")
  596. .setAlignment("center-center")
  597. .setText("L");
  598. m.Right_pylons = m.pylons_Group.createChild("text")
  599. .setColor(m.myGreen)
  600. .setTranslation(m.maxladderspan-60,100)
  601. .setDouble("character-size", 35)
  602. .setFont("LiberationFonts/LiberationMono-Bold.ttf")
  603. .setAlignment("center-center")
  604. .setText("D");
  605. m.Center_pylons = m.pylons_Group.createChild("text")
  606. .setColor(m.myGreen)
  607. .setTranslation(0,100)
  608. .setDouble("character-size", 35)
  609. .setFont("LiberationFonts/LiberationMono-Bold.ttf")
  610. .setAlignment("center-center")
  611. .setText("C");
  612. m.pylons_Group.hide();
  613. # Pylon selection letters
  614. m.pylons_Circle_Group = m.root.createChild("group");
  615. m.LeftCircle = m.pylons_Circle_Group.createChild("path")
  616. .setColor(m.myGreen)
  617. .moveTo(-m.maxladderspan+60+25, 100)
  618. .arcSmallCW(25,25, 0, -50, 0)
  619. .arcSmallCW(25,25, 0, 50, 0)
  620. .setStrokeLineWidth(5);
  621. m.RightCircle = m.pylons_Circle_Group.createChild("path")
  622. .setColor(m.myGreen)
  623. .moveTo(m.maxladderspan-60+25, 100)
  624. .arcSmallCW(25,25, 0, -50, 0)
  625. .arcSmallCW(25,25, 0, 50, 0)
  626. .setStrokeLineWidth(5);
  627. m.CenterCircle = m.pylons_Circle_Group.createChild("path")
  628. .setColor(m.myGreen)
  629. .moveTo(25, 100)
  630. .arcSmallCW(25,25, 0, -50, 0)
  631. .arcSmallCW(25,25, 0, 50, 0)
  632. .setStrokeLineWidth(5);
  633. m.pylons_Circle_Group.hide();
  634. #Take off Acceleration
  635. m.accBoxGroup = m.root.createChild("group");
  636. m.acceleration_Box = m.accBoxGroup.createChild("text")
  637. .setColor(m.myGreen)
  638. .setTranslation(0,0)
  639. .setDouble("character-size", 35)
  640. .setAlignment("center-center")
  641. .setText("0.00");
  642. m.accBoxLine = m.accBoxGroup.createChild("path")
  643. .setColor(m.myGreen)
  644. .moveTo(-70, -25)
  645. .horiz(140)
  646. .vert(50)
  647. .horiz(-140)
  648. .vert(-50)
  649. .setStrokeLineWidth(4);
  650. m.accBoxGroup.setTranslation(0,m.headScaleVerticalPlace*2/5);
  651. #Waypoint Group
  652. m.waypointGroup = m.root.createChild("group");
  653. m.waypointSimpleGroup = m.root.createChild("group");
  654. #Distance to next Waypoint
  655. m.waypointDistSimple = m.waypointSimpleGroup.createChild("text")
  656. .setColor(m.myGreen)
  657. .setTranslation( m.maxladderspan + 45 ,m.headScaleVerticalPlace*2/5)
  658. .setDouble("character-size", 30)
  659. .setAlignment("right-center")
  660. .setText("0");
  661. # N
  662. # m.waypointNSimple = m.waypointSimpleGroup.createChild("text")
  663. # .setTranslation( m.maxladderspan + 65 ,m.headScaleVerticalPlace*2/5)
  664. # .setDouble("character-size", 30)
  665. # .setAlignment("center-center")
  666. # .setText("N");
  667. #next Waypoint NUMBER
  668. m.waypointNumberSimple = m.waypointSimpleGroup.createChild("text")
  669. .setColor(m.myGreen)
  670. .setTranslation( m.maxladderspan + 85 ,m.headScaleVerticalPlace*2/5)
  671. .setDouble("character-size", 30)
  672. .setAlignment("left-center")
  673. .setText("00");
  674. #Distance to next Waypoint
  675. m.waypointDist = m.waypointGroup.createChild("text")
  676. .setColor(m.myGreen)
  677. .setTranslation( m.maxladderspan + 80 ,m.headScaleVerticalPlace*2/5)
  678. .setDouble("character-size", 30)
  679. .setAlignment("left-center")
  680. .setText("0");
  681. # N
  682. # m.waypointN = m.waypointGroup.createChild("text")
  683. # .setTranslation( m.maxladderspan + 120 ,m.headScaleVerticalPlace*2/5)
  684. # .setDouble("character-size", 30)
  685. # .setAlignment("left-center")
  686. # .setText("N");
  687. #next Waypoint NUMBER
  688. m.waypointNumber = m.waypointGroup.createChild("text")
  689. .setColor(m.myGreen)
  690. .setTranslation( m.maxladderspan + 80 ,m.headScaleVerticalPlace*2/5-25)
  691. .setDouble("character-size", 30)
  692. .setAlignment("left-center")
  693. .setText("00");
  694. #bull eye
  695. # m.BE = m.waypointGroup.createChild("text")
  696. # .setTranslation( m.maxladderspan + 55 ,m.headScaleVerticalPlace*2/5-25)
  697. # .setDouble("character-size", 30)
  698. # .setAlignment("right-center")
  699. # .setText("BE");
  700. m.DEST = m.waypointGroup.createChild("text")
  701. .setColor(m.myGreen)
  702. .setTranslation( m.maxladderspan + 55 ,m.headScaleVerticalPlace*2/5-25)
  703. .setDouble("character-size", 30)
  704. .setAlignment("right-center")
  705. .setText("DEST");
  706. #heading to the next Waypoint
  707. m.waypointHeading = m.waypointGroup.createChild("text")
  708. .setColor(m.myGreen)
  709. .setTranslation( m.maxladderspan + 65 ,m.headScaleVerticalPlace*2/5)
  710. .setDouble("character-size", 30)
  711. .setAlignment("right-center")
  712. .setText("000/");
  713. m.radarStuffGroup = m.root.createChild("group");
  714. #eegs funnel:
  715. #time * vectorSize >= 1.5
  716. m.eegsGroup = m.root.createChild("group");
  717. #m.averageDt = 0.050;
  718. m.averageDt = 0.10;
  719. #m.funnelParts = 10;
  720. m.funnelParts = 1.5 / m.averageDt;
  721. m.eegsRightX = [0];
  722. m.eegsRightY = [0];
  723. m.eegsLeftX = [0];
  724. m.eegsLeftY = [0];
  725. m.gunPos = nil;
  726. m.shellPosXInit = [0];
  727. m.shellPosYInit = [0];
  728. m.shellPosDistInit = [0];
  729. m.wingspanFT = 35;# 7- to 40 meter
  730. m.resetGunPos();
  731. m.eegsRightX = m.makeVector(m.funnelParts,0);
  732. m.eegsRightY = m.makeVector(m.funnelParts,0);
  733. m.eegsLeftX = m.makeVector(m.funnelParts,0);
  734. m.eegsLeftY = m.makeVector(m.funnelParts,0);
  735. m.eegsMe = {ac: geo.Coord.new(), eegsPos: geo.Coord.new(),shellPosX: m.makeVector(m.funnelParts,0),shellPosY: m.makeVector(m.funnelParts,0),shellPosDist: m.makeVector(m.funnelParts,0)};
  736. m.lastTime = systime();
  737. m.eegsLoop = maketimer(m.averageDt, m, m.displayEEGS);
  738. m.eegsLoop.simulatedTime = 1;
  739. #m.gunTemp = [nil,nil];
  740. # for(i = 0;i < m.funnelParts;i+=1){
  741. # append(m.eegsRightX,0);
  742. # append(m.eegsRightY,0);
  743. # append(m.eegsLeftX,0);
  744. # append(m.eegsLeftY,0);
  745. #print ("i:"~i);
  746. #print("size:"~size(m.gunPos));
  747. #print("size[i]:"~size(m.gunPos[i]));
  748. #print("After append size:"~size(m.gunPos));
  749. #print("After append size[i]:"~size(m.gunPos[i]));
  750. #print("After append size[i+1]:"~size(m.gunPos[i+1]));
  751. #append(m.gunPos,append(m.gunPos[i],[nil]));
  752. # append(m.shellPosXInit,0);
  753. # append(m.shellPosYInit,0);
  754. # append(m.shellPosDistInit,0);
  755. # }
  756. #
  757. #print(size(m.eegsRightX));
  758. #print(size(m.gunPos[size(m.gunPos)-1]));
  759. #m.eegsRightX = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
  760. #m.eegsRightY = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
  761. #m.eegsLeftX = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
  762. #m.eegsLeftY = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
  763. #m.gunPos = [[nil,nil],[nil,nil,nil],[nil,nil,nil,nil],[nil,nil,nil,nil,nil],[nil,nil,nil,nil,nil,nil],[nil,nil,nil,nil,nil,nil,nil],[nil,nil,nil,nil,nil,nil,nil,nil],[nil,nil,nil,nil,nil,nil,nil,nil,nil],[nil,nil,nil,nil,nil,nil,nil,nil,nil,nil],[nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil]];
  764. # m.eegsMe = {ac: geo.Coord.new(), eegsPos: geo.Coord.new(),
  765. # shellPosX: m.shellPosXInit,
  766. # shellPosY: m.shellPosYInit,
  767. # shellPosDist: m.shellPosDistInit};
  768. ################################### Runways #######################################
  769. m.myRunwayGroup = m.root.createChild("group");
  770. m.selectedRunway = 0;
  771. #################################### CCIP #########################################
  772. m.CCIP = m.root.createChild("group");
  773. # Bomb Fall Line (BFL)
  774. m.CCIP_BFL = m.CCIP.createChild("group");
  775. m.CCIP_BFL_line = m.CCIP_BFL.createChild("path");
  776. #Bomb impact
  777. m.CCIP_piper = m.CCIP.createChild("path")
  778. .setColor(m.myGreen)
  779. .moveTo(15, 0)
  780. .horiz(40)
  781. .moveTo(15, 0)
  782. .lineTo(7.5,13)
  783. .lineTo(-7.5,13)
  784. .lineTo(-15,0)
  785. .lineTo(-7.5,-13)
  786. .lineTo(7.5,-13)
  787. .lineTo(15,0)
  788. .moveTo(-15, 0)
  789. .horiz(-40)
  790. .setStrokeLineWidth(4);
  791. m.CCIP_safe_alt = m.CCIP.createChild("path")
  792. .setColor(m.myGreen)
  793. .moveTo(15, 0)
  794. .horiz(40)
  795. .vert(-15)
  796. .moveTo(-15, 0)
  797. .horiz(-40)
  798. .vert(-15)
  799. .setStrokeLineWidth(4);
  800. # Distance to impact
  801. m.CCIP_impact_dist = m.CCIP.createChild("text")
  802. .setColor(m.myGreen)
  803. .setTranslation(m.maxladderspan,-120)
  804. .setDouble("character-size", 35)
  805. .setAlignment("left-center")
  806. .setText("0.0");
  807. m.CCIP_no_go_cross = m.CCIP.createChild("path")
  808. .setColor(m.myGreen)
  809. .moveTo(80, 80)
  810. .lineTo(-80,-80)
  811. .moveTo(-80, 80)
  812. .lineTo(80,-80)
  813. .setStrokeLineWidth(4);
  814. #################################### CCRP #########################################
  815. m.CCRP = m.root.createChild("group");
  816. m.CCRP_Piper_group = m.CCRP.createChild("group");
  817. m.CCRP_piper = m.CCRP_Piper_group.createChild("path")
  818. .setColor(m.myGreen)
  819. .moveTo(24, 0)
  820. .lineTo(0,32)
  821. .lineTo(-24,0)
  822. .lineTo(0,-32)
  823. .lineTo(24,0)
  824. .moveTo(1,1)
  825. .lineTo(1,-1)
  826. .lineTo(-1,-1)
  827. .lineTo(-1,1)
  828. .moveTo(24, 0)
  829. .lineTo(44,0)
  830. .moveTo(-24, 0)
  831. .lineTo(-44,0)
  832. .setStrokeLineWidth(4);
  833. m.CCRP_Deviation = m.CCRP_Piper_group.createChild("path")
  834. .setColor(m.myGreen)
  835. .moveTo(34, 0)
  836. .lineTo(80,0)
  837. .moveTo(-34, 0)
  838. .lineTo(-80,0)
  839. .setStrokeLineWidth(4);
  840. #m.CCRP_Piper_group.setTranslation(0,-250);
  841. m.CCRP_release_cue = m.CCRP.createChild("path")
  842. .setColor(m.myGreen)
  843. .moveTo(55, 0)
  844. .horiz(-110)
  845. .setStrokeLineWidth(4);
  846. # Distance to target
  847. m.CCRP_impact_dist = m.CCRP.createChild("text")
  848. .setColor(m.myGreen)
  849. .setTranslation(m.maxladderspan,-120)
  850. .setDouble("character-size", 35)
  851. .setAlignment("left-center")
  852. .setText("0.0");
  853. m.CCRP_no_go_cross = m.CCRP.createChild("path")
  854. .setColor(m.myGreen)
  855. .moveTo(80, 80)
  856. .lineTo(-80,-80)
  857. .moveTo(-80, 80)
  858. .lineTo(80,-80)
  859. .setStrokeLineWidth(4);
  860. ##################################### Target Circle ####################################
  861. m.targetArray = [];
  862. m.circle_group2 = m.radarStuffGroup.createChild("group");
  863. for(var i = 1; i <= m.MaxTarget; i += 1){
  864. myCircle = m.circle_group2.createChild("path")
  865. .setColor(m.myGreen)
  866. .moveTo(25, 0)
  867. .arcSmallCW(25,25, 0, -50, 0)
  868. .arcSmallCW(25,25, 0, 50, 0)
  869. .setStrokeLineWidth(5)
  870. ;
  871. append(m.targetArray, myCircle);
  872. }
  873. m.targetrot = m.circle_group2.createTransform();
  874. ####################### Info Text ########################################
  875. m.TextInfoArray = [];
  876. m.TextInfoGroup = m.radarStuffGroup.createChild("group");
  877. for(var i = 1; i <= m.MaxTarget; i += 1){
  878. # on affiche des infos de la cible a cote du cercle
  879. text_info = m.TextInfoGroup.createChild("text", "infos")
  880. .setColor(m.myGreen)
  881. .setTranslation(15, -10)
  882. .setAlignment("left-center")
  883. .setFont("LiberationFonts/LiberationSansNarrow-Bold.ttf")
  884. .setFontSize(26)
  885. .setColor(0,180,0,0.9)
  886. .setText("VOID");
  887. append(m.TextInfoArray, text_info);
  888. }
  889. m.Textrot = m.TextInfoGroup.createTransform();
  890. ####################### Triangles ##########################################
  891. var TriangleSize = 30;
  892. m.TriangleGroupe = m.radarStuffGroup.createChild("group");
  893. # le triangle donne le cap relatif
  894. m.triangle = m.TriangleGroupe.createChild("path")
  895. .setColor(m.myGreen)
  896. .setStrokeLineWidth(3)
  897. .moveTo(0, TriangleSize*-1)
  898. .lineTo(TriangleSize*0.866, TriangleSize*0.5)
  899. .lineTo(TriangleSize*-0.866, TriangleSize*0.5)
  900. .lineTo(0, TriangleSize*-1);
  901. TriangleSize = TriangleSize*0.7;
  902. m.triangle2 = m.TriangleGroupe.createChild("path")
  903. .setColor(m.myGreen)
  904. .setStrokeLineWidth(3)
  905. .moveTo(0, TriangleSize*-1)
  906. .lineTo(TriangleSize*0.866, TriangleSize*0.5)
  907. .lineTo(TriangleSize*-0.866, TriangleSize*0.5)
  908. .lineTo(0, TriangleSize*-1.1);
  909. m.triangleRot = m.TriangleGroupe.createTransform();
  910. m.TriangleGroupe.hide();
  911. m.Square_Group = m.radarStuffGroup.createChild("group");
  912. m.Locked_Square = m.Square_Group.createChild("path")
  913. .setColor(m.myGreen)
  914. .move(-25,-25)
  915. .vert(50)
  916. .horiz(50)
  917. .vert(-50)
  918. .horiz(-50)
  919. .setStrokeLineWidth(6);
  920. m.Locked_Square_Dash = m.Square_Group.createChild("path")
  921. .setColor(m.myGreen)
  922. .move(-25,-25)
  923. .vert(50)
  924. .horiz(50)
  925. .vert(-50)
  926. .horiz(-50)
  927. .setStrokeDashArray([10,10])
  928. .setStrokeLineWidth(5);
  929. m.Square_Group.hide();
  930. m.missileFireRange = m.root.createChild("group");
  931. m.MaxFireRange = m.missileFireRange.createChild("path")
  932. .setColor(m.myGreen)
  933. .moveTo(210,0)
  934. .horiz(-30)
  935. .setStrokeLineWidth(6);
  936. m.MinFireRange = m.missileFireRange.createChild("path")
  937. .setColor(m.myGreen)
  938. .moveTo(210,0)
  939. .horiz(-30)
  940. .setStrokeLineWidth(6);
  941. m.NEZFireRange = m.missileFireRange.createChild("path")
  942. .setColor(m.myGreen)
  943. .moveTo(215,0)
  944. .horiz(-40)
  945. .setStrokeLineWidth(4);
  946. m.missileFireRange.hide();
  947. m.distanceToTargetLineGroup = m.root.createChild("group");
  948. m.distanceToTargetLineMin = -100;
  949. m.distanceToTargetLineMax = 100;
  950. m.distanceToTargetLine = m.distanceToTargetLineGroup.createChild("path")
  951. .setColor(m.myGreen)
  952. .moveTo(200,m.distanceToTargetLineMin)
  953. .horiz(30)
  954. .moveTo(200,m.distanceToTargetLineMin)
  955. .vert(m.distanceToTargetLineMax-m.distanceToTargetLineMin)
  956. .horiz(30)
  957. .setStrokeLineWidth(5);
  958. m.distanceToTargetLineTextGroup = m.distanceToTargetLineGroup.createChild("group");
  959. m.distanceToTargetLineChevron = m.distanceToTargetLineTextGroup.createChild("text")
  960. .setColor(m.myGreen)
  961. .setTranslation(200,0)
  962. .setDouble("character-size", 60)
  963. .setAlignment("left-center")
  964. .setText("<");
  965. m.distanceToTargetLineChevronText = m.distanceToTargetLineTextGroup.createChild("text")
  966. .setColor(m.myGreen)
  967. .setTranslation(230,0)
  968. .setDouble("character-size", 40)
  969. .setAlignment("left-center")
  970. .setText("x");
  971. m.distanceToTargetLineGroup.hide();
  972. # obj.ASC = obj.svg.createChild("path")# (Attack Steering Cue (ASC))
  973. # .moveTo(-8*mr,0)
  974. # .arcSmallCW(8*mr,8*mr, 0, 8*mr*2, 0)
  975. # .arcSmallCW(8*mr,8*mr, 0, -8*mr*2, 0)
  976. # .setStrokeLineWidth(1)
  977. # .setColor(0,1,0).hide();
  978. # append(obj.total, obj.ASC);
  979. m.root.setColor(m.red,m.green,m.blue,1);
  980. m.loads_hash = {
  981. "30mm Cannon":"CAN",
  982. "Magic-2": "MAG",
  983. "S530D":"530",
  984. "MICA-IR":"MIC-I",
  985. "MICA-EM":"MIC-E",
  986. "GBU-12": "GBU12",
  987. "SCALP": "SCALP",
  988. "APACHE": "APACHE",
  989. "AM39-Exocet":"AM39",
  990. "AS-37-Martel":"AS37",
  991. "AS-37-Armat":"AS37A",
  992. "AS30L" :"AS30",
  993. "Mk-82" : "Mk82",
  994. "Mk-82SE":"Mk82S",
  995. "GBU-24":"GBU24"
  996. };
  997. m.pylonsSide_hash = {
  998. 0 : "L",
  999. 1 : "L",
  1000. 2 : "L",
  1001. 7 : "L",
  1002. 3 : "C",
  1003. 4 : "R",
  1004. 5 : "R",
  1005. 6 : "R",
  1006. 8 : "R",
  1007. };
  1008. m.input = {
  1009. pitch: "/orientation/pitch-deg",
  1010. roll: "/orientation/roll-deg",
  1011. hdg: "/orientation/heading-magnetic-deg",
  1012. hdgReal: "/orientation/heading-deg",
  1013. hdgBug: "/autopilot/settings/heading-bug-deg",
  1014. hdgDisplay: "/instrumentation/efis/mfd/true-north",
  1015. speed_n: "velocities/speed-north-fps",
  1016. speed_e: "velocities/speed-east-fps",
  1017. speed_d: "velocities/speed-down-fps",
  1018. uBody_fps: "velocities/uBody-fps",
  1019. alpha: "/orientation/alpha-deg",
  1020. beta: "/orientation/side-slip-deg",
  1021. gload: "/accelerations/pilot-g",
  1022. ias: "/velocities/airspeed-kt",
  1023. mach: "/velocities/mach",
  1024. gs: "/velocities/groundspeed-kt",
  1025. vs: "/velocities/vertical-speed-fps",
  1026. alt: "/position/altitude-ft",
  1027. alt_instru: "/instrumentation/altimeter/indicated-altitude-ft",
  1028. rad_alt: "position/altitude-agl-ft", #"/instrumentation/radar-altimeter/radar-altitude-ft",
  1029. wow_nlg: "/gear/gear[1]/wow",
  1030. gearPos: "/gear/gear[1]/position-norm",
  1031. airspeed: "/velocities/airspeed-kt",
  1032. target_spd: "/autopilot/settings/target-speed-kt",
  1033. acc: "/fdm/jsbsim/accelerations/udot-ft_sec2",
  1034. afterburner: "/engines/engine[0]/afterburner",
  1035. NavFreq: "/instrumentation/nav/frequencies/selected-mhz",
  1036. destRunway: "/autopilot/route-manager/destination/runway",
  1037. destAirport:"/autopilot/route-manager/destination/airport",
  1038. distNextWay:"/autopilot/route-manager/wp/dist",
  1039. NextWayNum :"/autopilot/route-manager/current-wp",
  1040. NextWayTrueBearing:"/autopilot/route-manager/wp/true-bearing-deg",
  1041. NextWayBearing:"/autopilot/route-manager/wp/bearing-deg",
  1042. AutopilotStatus:"/autopilot/locks/AP-status",
  1043. currentWp : "/autopilot/route-manager/current-wp",
  1044. ILS_valid :"/instrumentation/nav/data-is-valid",
  1045. NavHeadingRunwayILS:"/instrumentation/nav/heading-deg",
  1046. ILS_gs_in_range :"/instrumentation/nav/gs-in-range",
  1047. ILS_gs_deg: "/instrumentation/nav/gs-direct-deg",
  1048. NavHeadingNeedleDeflectionILS:"/instrumentation/nav/heading-needle-deflection-norm",
  1049. x_offset_m: "/sim/current-view/x-offset-m",
  1050. y_offset_m: "/sim/current-view/y-offset-m",
  1051. z_offset_m: "/sim/current-view/z-offset-m",
  1052. MasterArm :"/controls/armament/master-arm",
  1053. TimeToTarget :"/sim/dialog/groundtTargeting/time-to-target",
  1054. IsRadarWorking : "/systems/electrical/outputs/radar",
  1055. gun_rate : "/ai/submodels/submodel[1]/delay",
  1056. bullseye_lat : "/instrumentation/bullseye/bulls-eye-lat",
  1057. bullseye_lon : "instrumentation/bullseye/bulls-eye-lon",
  1058. bullseye_def : "instrumentation/bullseye/bulls-eye-defined"
  1059. };
  1060. foreach(var name; keys(m.input)){
  1061. m.input[name] = props.globals.getNode(m.input[name], 1);
  1062. }
  1063. m.lastWP = m.input.currentWp.getValue();
  1064. m.RunwayCoord = geo.Coord.new();
  1065. m.RunwaysCoordCornerLeft = geo.Coord.new();
  1066. m.RunwaysCoordCornerRight = geo.Coord.new();
  1067. m.RunwaysCoordEndCornerLeft = geo.Coord.new();
  1068. m.RunwaysCoordEndCornerRight = geo.Coord.new();
  1069. m.bullseyeGeo = geo.Coord.new();
  1070. m.NXTWP = geo.Coord.new();
  1071. return m;
  1072. },
  1073. update: func()
  1074. {
  1075. me.aircraft_position = geo.aircraft_position();
  1076. me.hydra = 0; #for rocket
  1077. me.strf = me.input.gun_rate.getValue()==0.06?1:0; #Air to ground fire : based on the gun rate
  1078. #me.airspeed.setText(sprintf("%d", me.input.ias.getValue()));
  1079. #me.groundspeed.setText(sprintf("G %3d", me.input.gs.getValue()));
  1080. #me.vertical_speed.setText(sprintf("%.1f", me.input.vs.getValue() * 60.0 / 1000));
  1081. HudMath.reCalc();
  1082. #loading Flightplan
  1083. me.fp = flightplan();
  1084. #Choose the heading to display
  1085. me.getHeadingToDisplay();
  1086. #-----------------Test of paralax
  1087. me.Vy = me.input.x_offset_m.getValue();
  1088. me.pixelPerMeterX = HudMath.pixelPerMeterX;#(340*0.695633)/0.15848;
  1089. #me.pixelPerMeterY = 260/(me.Hz_t-me.Hz_b);
  1090. me.pixelside = me.pixelPerMeterX*me.Vy;
  1091. #me.svg.setTranslation(me.pixelside, 0);
  1092. #me.custom.setTranslation(me.pixelside, 0);
  1093. me.root.setTranslation(HudMath.getCenterOrigin()[0]+me.pixelside, HudMath.getCenterOrigin()[1]);
  1094. #me.custom.update();
  1095. me.root.update();
  1096. #me.svg.update();
  1097. #Think this code sucks. If everyone have better, please, proceed :)
  1098. #Weapons management should be in a function.
  1099. #Taking radar should be done once for all
  1100. #missile management aren't made : it should be
  1101. me.eegsShow=0;
  1102. me.selectedWeap = pylons.fcs.getSelectedWeapon();
  1103. me.Fire_GBU.setText("Fire");
  1104. me.showFire_GBU = 0;
  1105. me.show_CCIP = 0;
  1106. me.show_CCRP = 0;
  1107. me.CCRP_Piper_group_visibilty = 1;
  1108. me.CCRP_cue_visbility = 0;
  1109. me.CCRP_no_go_cross_visibility = 0;
  1110. if(me.selectedWeap != nil and me.input.MasterArm.getValue()){
  1111. if(me.selectedWeap.type != "30mm Cannon"){
  1112. #Doing the math only for bombs
  1113. if(me.selectedWeap.stage_1_duration+me.selectedWeap.stage_2_duration == 0){
  1114. if(mirage2000.myRadar3.tgts_list != nil and size(mirage2000.myRadar3.tgts_list) > 0){
  1115. #if target selected : CCRP
  1116. #print("Should CCRP : size target list" ~ size(mirage2000.myRadar3.tgts_list));
  1117. me.show_CCRP = me.display_CCRP_mode();
  1118. }else{
  1119. #Else CCIP
  1120. #print("Should CCIP");
  1121. me.show_CCIP = me.display_CCIP_mode();
  1122. #print("Distance to shoot : nil");
  1123. }
  1124. }
  1125. }else{
  1126. #Else showing the gun
  1127. me.eegsShow=me.input.MasterArm.getValue();
  1128. }
  1129. }
  1130. #CCRP visibility :
  1131. #piper when we have a target
  1132. #Cue line when time to target < 15
  1133. #Cross when speed <350
  1134. #target and house (to be defined)
  1135. me.CCRP.setVisible(me.show_CCRP);
  1136. me.CCRP_Piper_group.setVisible(me.CCRP_Piper_group_visibilty);
  1137. me.CCRP_release_cue.setVisible( me.CCRP_cue_visbility);
  1138. me.CCRP_no_go_cross.setVisible(me.CCRP_no_go_cross_visibility);
  1139. me.Fire_GBU.setVisible(me.showFire_GBU);
  1140. #CCIP Visibility
  1141. me.CCIP.setVisible(me.show_CCIP);
  1142. #me.hdg.setText(sprintf("%03d", me.input.hdg.getValue()));
  1143. me.horizStuff = HudMath.getStaticHorizon();
  1144. me.horizon_group.setTranslation(me.horizStuff[0]);
  1145. me.h_rot.setRotation(me.horizStuff[1]);
  1146. me.horizon_sub_group.setTranslation(me.horizStuff[2]);
  1147. # var rot = -me.input.roll.getValue() * math.pi / 180.0;
  1148. #me.Textrot.setRotation(rot);
  1149. #Displaying ILS STUFF (but only show after LOCALIZER capture)
  1150. me.display_ILS_STUFF();
  1151. #ILS not dependent of the Scale (but only show after GS capture)
  1152. me.display_ILS_Square();
  1153. #me.RunwayOnTheHorizonLine.hide();
  1154. # Bore Cross. In navigation, the cross should only appear on NextWaypoint gps cooord, when dist to this waypoint is bellow 10 nm
  1155. #me.NXTWP = geo.Coord.new();
  1156. #Calculate the GPS coord of the next WP
  1157. me.NextWaypointCoordinate();
  1158. if(me.input.bullseye_def.getValue()){
  1159. if(me.input.bullseye_lat.getValue() != nil and me.input.bullseye_lon.getValue() != nil){
  1160. me.bullseyeGeo.set_latlon(me.input.bullseye_lat.getValue(),me.input.bullseye_lon.getValue());
  1161. }
  1162. }
  1163. #Display the Next WP ##################################################
  1164. #Should be displayed for :
  1165. #1-Next waypoint
  1166. #2-bulleseye
  1167. #3-ground target
  1168. me.displayWaypointCrossShow = 0;
  1169. me.display_houseShow = 0;
  1170. me.waypointGroupshow = 0;
  1171. me.waypointSimpleGroupShow = 0;
  1172. if(me.input.gearPos.getValue() == 0){# if masterArm is not selected
  1173. #if there is a route selected and Bulleye isn't selected
  1174. if( me.NXTWP.is_defined() and !me.input.MasterArm.getValue()){#if waypoint is active
  1175. me.displayWaypointCross(me.NXTWP); # displaying the ground cross
  1176. me.display_house(me.NXTWP); # displaying the little house
  1177. me.display_Waypoint(me.NXTWP,"DEST",me.input.NextWayNum.getValue());
  1178. }
  1179. if(me.input.bullseye_def.getValue()){
  1180. me.displayWaypointCross(me.bullseyeGeo); # displaying the ground cross
  1181. me.display_house(me.bullseyeGeo); # displaying the little house
  1182. me.display_Waypoint(me.bullseyeGeo,"BE ",nil);
  1183. }
  1184. }
  1185. me.WaypointCross.setVisible(me.displayWaypointCrossShow);
  1186. me.HeadingHouse.setVisible(me.display_houseShow);
  1187. me.waypointGroup.setVisible(me.waypointGroupshow);
  1188. me.waypointSimpleGroup.setVisible(0);
  1189. ###################################################
  1190. #Gun Cross (bore)
  1191. me.displayBoreCross();
  1192. # flight path vector (FPV)
  1193. me.display_Fpv();
  1194. #chevronGroup
  1195. me.display_Chevron();
  1196. #Don't know what that does ...
  1197. # var speed_error = 0;
  1198. # if( me.input.target_spd.getValue() != nil )
  1199. # speed_error = 4 * clamp(
  1200. # me.input.target_spd.getValue() - me.input.airspeed.getValue(),
  1201. # -15, 15
  1202. # );
  1203. #Acc accBoxGroup in G(so I guess /9,8)
  1204. me.display_Acceleration_Box();
  1205. #display_radarAltimeter
  1206. me.display_radarAltimeter();
  1207. #Display speedAltGroup
  1208. me.display_speedAltGroup();
  1209. #Display diplay_inverted_T
  1210. me.display_inverted_T();
  1211. #Display aoa
  1212. me.display_alpha();
  1213. #Display gload
  1214. me.display_gload();
  1215. #Diplay Load type
  1216. me.display_loadsType();
  1217. #Display bullet Count
  1218. me.display_BulletCount();
  1219. #Display selected
  1220. me.displaySelectedPylons();
  1221. #Display Route dist and waypoint number
  1222. #me.display_Waypoint();
  1223. #me.hdg.hide();
  1224. #me.groundspeed.hide();
  1225. #me.rad_alt.hide();
  1226. #me.airspeed.hide();
  1227. #me.energy_cue.hide();
  1228. #me.acc.hide();
  1229. #me.vertical_speed.hide();
  1230. #Displaying the circles, the squares or even the triangles (triangles will be for a IR lock without radar)
  1231. me.displayTarget();
  1232. #--------------------- Selecting the Airport and the runway -------------
  1233. #------------------------------------------------------------------------
  1234. #Need to select the runways and write the conditions
  1235. #2. SYNTHETIC RUNWAY. The synthetic runway symbol is an aid for locating the real runway, especially during low visibility conditions.
  1236. #It is only visible when:
  1237. #a. The INS is on.
  1238. #b. The airport is the current fly-to waypoint.
  1239. #c. The runway data (heading and glideslope) were entered.
  1240. #d. Both localizer and glideslope have been captured
  1241. #e. The runway is less than 10 nautical miles away.
  1242. #f. Lateral deviation is less than 7º.
  1243. # The synthetic runway is removed from the HUD as soon as there is weight on the landing gear’s wheels.
  1244. #First trying with ILS
  1245. #var NavFrequency = getprop("/instrumentation/nav/frequencies/selected-mhz");
  1246. me.selectedRunway = "0";
  1247. #print("-- Lengths of the runways at ", info.name, " (", info.id, ") --");
  1248. me.info = airportinfo();
  1249. foreach(var rwy; keys(me.info.runways)){
  1250. if(sprintf("%.2f",me.info.runways[rwy].ils_frequency_mhz) == sprintf("%.2f",me.input.NavFreq.getValue())){
  1251. me.selectedRunway = rwy;
  1252. }
  1253. }
  1254. #Then, trying with route manager
  1255. if(me.selectedRunway == "0" and !me.input.MasterArm.getValue()){
  1256. if(me.input.destRunway.getValue() != ""){
  1257. if(me.fp.getPlanSize() == me.fp.indexOfWP(me.fp.currentWP())+1){
  1258. me.info = airportinfo(me.input.destAirport.getValue());
  1259. me.selectedRunway = me.input.destRunway.getValue() ;
  1260. }
  1261. }
  1262. }
  1263. #print("Test : ",me.selectedRunway != "0");
  1264. if(me.selectedRunway != "0" and !me.input.MasterArm.getValue()){
  1265. var (courseToAiport, distToAirport) = courseAndDistance(me.info);
  1266. if( distToAirport < 10 and me.input.wow_nlg.getValue() == 0){
  1267. me.displayRunway();
  1268. }else{
  1269. me.myRunwayGroup.removeAllChildren();
  1270. }
  1271. }else{
  1272. me.myRunwayGroup.removeAllChildren();
  1273. }
  1274. # -------------------- displayHeadingHorizonScale ---------------
  1275. me.displayHeadingHorizonScale();
  1276. # -------------------- display_heading_bug ---------------
  1277. me.display_heading_bug();
  1278. #---------------------- EEFS --------------------
  1279. if (!me.eegsShow) {
  1280. me.eegsGroup.setVisible(me.eegsShow);
  1281. }
  1282. if (me.eegsShow and !me.eegsLoop.isRunning) {
  1283. me.eegsLoop.start();
  1284. } elsif (!me.eegsShow and me.eegsLoop.isRunning) {
  1285. me.eegsLoop.stop();
  1286. }
  1287. #settimer(func me.update(), 0.1);
  1288. me.lastWP = me.input.currentWp.getValue();
  1289. #------------------------End of the Update------------------------------------------------------------------------
  1290. },
  1291. display_ILS_STUFF:func(){
  1292. if(me.input.ILS_valid.getValue() and !me.input.MasterArm.getValue()){
  1293. me.runwayPosHrizonOnHUD = HudMath.getPixelPerDegreeXAvg(7.5)*-(geo.normdeg180(me.heading - me.input.NavHeadingRunwayILS.getValue() ));
  1294. me.ILS_Scale_dependant.setTranslation(me.runwayPosHrizonOnHUD,0);
  1295. #me.ILS_localizer_deviation.setCenter(me.runwayPosHrizonOnHUD,0);
  1296. me.ILS_localizer_deviation.setRotation(-45*me.input.NavHeadingNeedleDeflectionILS.getValue()*D2R);
  1297. me.ILS_Scale_dependant.update();
  1298. me.ILS_Scale_dependant.show();
  1299. }else{
  1300. me.ILS_Scale_dependant.hide();
  1301. }
  1302. },
  1303. display_CCIP_mode:func(){
  1304. #CCIP : for bomb dropping.
  1305. #Source : DCS manual / tutorials
  1306. me.ccipPos = me.selectedWeap.getCCIPadv(me.input.TimeToTarget.getValue(), 0.20);
  1307. if(me.ccipPos != nil){
  1308. me.hud_pos = HudMath.getPosFromCoord(me.ccipPos[0]);
  1309. if(me.hud_pos != nil) {
  1310. me.pos_x = me.hud_pos[0];
  1311. me.pos_y = me.hud_pos[1];
  1312. me.CCIP_piper.setTranslation(me.pos_x,me.pos_y);
  1313. #Updating : clear all previous stuff
  1314. me.CCIP_BFL.removeAllChildren();
  1315. #Drawing the line
  1316. me.CCIP_BFL_line = me.CCIP_BFL.createChild("path")
  1317. .setColor(me.myGreen)
  1318. .moveTo(me.fpvCalc)
  1319. .lineTo(me.pos_x,me.pos_y)
  1320. .setStrokeLineWidth(4);
  1321. #Calculate safe alt :
  1322. #me.selectedWeap.reportDist*2) is an arbitrary choice
  1323. me.safe_alt = int(me.ccipPos[0].alt()+me.selectedWeap.reportDist*2);
  1324. #print("me.safe_alt:" ~me.safe_alt);
  1325. #print("diff elevation vs target_alt:" ~ int(me.input.alt.getValue()*FT2M));
  1326. #print("%off line : " ~ me.safe_alt/(me.input.alt.getValue()*FT2M));
  1327. me.safe_alt_pourcent = me.safe_alt/(me.input.alt.getValue());
  1328. me.CCIP_safe_alt.setTranslation(me.fpvCalc[0],me.fpvCalc[1]-(me.fpvCalc[1]-me.pos_y)*(1-clamp(me.safe_alt_pourcent,0,1)));
  1329. #Distance to ground impact : only working if radar is on
  1330. if(me.input.IsRadarWorking.getValue()>24){
  1331. me.CCIP_impact_dist.setText(sprintf("%.1f KM", me.ccipPos[0].direct_distance_to(geo.aircraft_position())/1000));
  1332. }else{
  1333. me.CCIP_impact_dist.setText(sprintf("%.1f KM", 0));
  1334. }
  1335. #No go : too dangerous to drop the bomb
  1336. me.CCIP_no_go_cross.setVisible(me.safe_alt_pourcent>0.85);
  1337. return 1;
  1338. }
  1339. }
  1340. return 0;
  1341. },
  1342. display_CCRP_mode:func(){
  1343. #print("Class of Load:" ~ me.selectedWeap.class);
  1344. me.DistanceToShoot = nil;
  1345. me.DistanceToShoot = me.selectedWeap.getCCRP(me.input.TimeToTarget.getValue(), 0.05);
  1346. if(me.DistanceToShoot != nil ){
  1347. # This should be the CCRP function
  1348. # The no go CCRP is when speed < 350 kts.
  1349. # We need the house and the nav point display to display the target.
  1350. # the CCRP piper is a fixed pointand replace the FPV
  1351. # CCRP steering cues:
  1352. # They appear only after a target point has been selected. They are centered on the
  1353. # CCRP piper and rotate to show deviation from the course to target. The aircraft is
  1354. # flying directly to the target when they are level.
  1355. #if(me.DistanceToShoot/ (me.input.gs.getValue() * KT2MPS) < 30){
  1356. #me.showFire_GBU = 1;
  1357. #me.Fire_GBU.setText(sprintf("TTR: %d ", int(me.DistanceToShoot/ (me.input.gs.getValue() * KT2MPS))));
  1358. if(me.DistanceToShoot/ (me.input.gs.getValue() * KT2MPS) < 15){
  1359. #me.Fire_GBU.setText(sprintf("Fire : %d ", int(me.DistanceToShoot/ (me.input.gs.getValue() * KT2MPS))));
  1360. me.BorePos = HudMath.getBorePos();
  1361. me.hud_pos = HudMath.getPosFromCoord(me.selectedWeap.Tgt.get_Coord());
  1362. if(me.hud_pos != nil) {
  1363. #print('CCRP_release_cue should move');
  1364. me.pos_x = me.hud_pos[0];
  1365. me.pos_y = me.hud_pos[1];
  1366. me.CCRP_release_percent = (me.DistanceToShoot/ (me.input.gs.getValue() * KT2MPS))/30;
  1367. me.CCRP_release_cue.setTranslation(me.BorePos[0],me.BorePos[1]-(me.BorePos[1]-me.pos_y)*(clamp(me.CCRP_release_percent,0,1)));
  1368. me.CCRP_cue_visbility = 1;
  1369. }
  1370. }
  1371. #}
  1372. printf("me.DistanceToShoot: %.2f ; Time to shoot : %.2f",me.DistanceToShoot,me.DistanceToShoot/ (me.input.gs.getValue() * KT2MPS));
  1373. print("Deviation:"~me.selectedWeap.Tgt.get_deviation(me.input.hdgReal.getValue(), geo.aircraft_position()));
  1374. }
  1375. # The no go CCRP is when speed < 350 kts.
  1376. if(me.input.airspeed.getValue()<350){
  1377. me.CCRP_no_go_cross_visibility = 1;
  1378. }
  1379. #There is a target so the piper and the deviation should get displayed.
  1380. me.CCRP_Piper_group.setTranslation(HudMath.getBorePos());
  1381. if(me.selectedWeap.Tgt != nil){
  1382. # * 10 to see if that can improves precisions
  1383. me.CCRP_Deviation.setRotation(me.selectedWeap.Tgt.get_deviation(me.input.hdgReal.getValue(), geo.aircraft_position())*D2R*2);
  1384. }
  1385. return 1;
  1386. },
  1387. display_ILS_Square:func(){
  1388. if(me.input.ILS_gs_in_range.getValue()and !me.input.MasterArm.getValue()){
  1389. me.ILS_Square.setTranslation(0,HudMath.getCenterPosFromDegs(0,-me.input.ILS_gs_deg.getValue()-me.input.pitch.getValue())[1]);
  1390. #me.ILS_Square.update();
  1391. me.brackets.setTranslation(0,HudMath.getCenterPosFromDegs(0,me.input.pitch.getValue()-14)[1]);
  1392. me.ILS_Scale_Independant.update();
  1393. me.ILS_Scale_Independant.show();
  1394. }else{
  1395. me.ILS_Scale_Independant.hide();
  1396. }
  1397. },
  1398. getHeadingToDisplay:func(){
  1399. if(me.input.hdgDisplay.getValue()){
  1400. me.heading = me.input.hdgReal.getValue();
  1401. }else{
  1402. me.heading = me.input.hdg.getValue();
  1403. }
  1404. },
  1405. displayHeadingHorizonScale:func(){
  1406. #we only need those digit : this tricks avoid too much drawing
  1407. me.headOffset = me.heading/10 - int (me.heading/10);
  1408. me.headScaleOffset = me.headOffset;
  1409. me.middleText = roundabout(me.heading/10);
  1410. me.middleText = me.middleText == 36?0:me.middleText;
  1411. me.leftText = me.middleText == 0?35:me.middleText-1;
  1412. me.rightText = me.middleText == 35?0:me.middleText+1;
  1413. me.rightRightText = me.rightText == 35?0:me.rightText+1;
  1414. if (me.headOffset > 0.5) {
  1415. me.middleOffset = -(me.headScaleOffset-1)*me.headScaleTickSpacing*2;
  1416. } else {
  1417. me.middleOffset = -me.headScaleOffset*me.headScaleTickSpacing*2;
  1418. }
  1419. me.headingScaleGroup.setTranslation(me.middleOffset , 0);
  1420. me.hdgRH.setText(sprintf("%02d", me.rightText));
  1421. me.hdgMH.setText(sprintf("%02d", me.middleText));
  1422. me.hdgLH.setText(sprintf("%02d", me.leftText));
  1423. me.hdgRRH.setText(sprintf("%02d", me.rightRightText));
  1424. #me.hdgMH.setTranslation(me.middleOffset , 0);
  1425. me.headingScaleGroup.update();
  1426. },
  1427. # flight path vector (FPV)
  1428. display_Fpv:func(){
  1429. me.fpvCalc = HudMath.getFlightPathIndicatorPosWind();
  1430. me.fpv.setTranslation(me.fpvCalc);
  1431. if(me.input.AutopilotStatus.getValue()=="AP1"){
  1432. me.AutopilotStar.setTranslation(me.fpvCalc);
  1433. me.AutopilotStar.show();
  1434. }else{
  1435. me.AutopilotStar.hide();
  1436. }
  1437. },
  1438. #This should be called with a geo.coord object.
  1439. #Doing that way it could be used for waypoint, bullseye and ground target
  1440. display_house:func(coord){
  1441. if(coord != nil){
  1442. if(!me.isInCanvas(HudMath.getPosFromCoord(coord)[0],HudMath.getPosFromCoord(coord)[1]) or me.aircraft_position.direct_distance_to(coord)*M2NM >=10 ){
  1443. #Depend of which heading we want to display
  1444. if(me.input.hdgDisplay.getValue()){
  1445. me.houseTranslation = -(geo.normdeg180(me.heading - me.aircraft_position.course_to(coord)))*me.headScaleTickSpacing/5;
  1446. }else{
  1447. me.houseTranslation = -(geo.normdeg180(me.heading - me.aircraft_position.course_to(coord)))*me.headScaleTickSpacing/5;
  1448. }
  1449. me.HeadingHouse.setTranslation(clamp(me.houseTranslation,-me.maxladderspan,me.maxladderspan),me.fpvCalc[1]);
  1450. if(abs(me.houseTranslation/(me.headScaleTickSpacing/5))>90){
  1451. me.HeadingHouse.setRotation(me.horizStuff[1]+(180* D2R));
  1452. }else{
  1453. me.HeadingHouse.setRotation(me.horizStuff[1]);
  1454. }
  1455. me.display_houseShow = 1;
  1456. return;
  1457. }
  1458. }
  1459. #me.HeadingHouse.hide();
  1460. },
  1461. display_Chevron : func(){
  1462. if(me.input.afterburner.getValue()){me.chevronGroupAB.show();}else{me.chevronGroupAB.hide();}
  1463. me.chevronGroup.setTranslation(me.fpvCalc[0],me.fpvCalc[1]-me.input.acc.getValue()*FT2M*me.chevronFactor);
  1464. me.chevronGroup.update();
  1465. },
  1466. display_heading_bug : func(){
  1467. headOffset = -(geo.normdeg180(me.heading - me.input.hdgBug.getValue() ))*me.headScaleTickSpacing/5;
  1468. me.head_scale_route_pointer.setTranslation(headOffset,0);
  1469. me.headingScaleGroup.update();
  1470. },
  1471. display_Acceleration_Box:func(){
  1472. #Acc accBoxGroup in G(so I guess /9,8)
  1473. if(me.input.wow_nlg.getValue()){
  1474. me.acceleration_Box.setText(sprintf("%.2f", int(me.input.acc.getValue()*FT2M/9.8*1000+1)/1000));
  1475. me.accBoxGroup.show();
  1476. }else{
  1477. me.accBoxGroup.hide();
  1478. }
  1479. me.accBoxGroup.update();
  1480. },
  1481. display_speedAltGroup:func(){
  1482. me.Speed.setText(sprintf("%d",int(me.input.ias.getValue())));
  1483. if(me.input.mach.getValue()>= 0.6){
  1484. me.Speed_Mach.setText(sprintf("%0.2f",me.input.mach.getValue()));
  1485. me.Speed_Mach.show();
  1486. }else{
  1487. me.Speed_Mach.hide();
  1488. }
  1489. #print("Alt:",me.input.alt.getValue()," Calcul:" ,int(((me.input.alt.getValue()/100) - int(me.input.alt.getValue()/100))*100));
  1490. me.feet_Alt.setText(sprintf("%02d",abs(int(((me.input.alt_instru.getValue()/100) - int(me.input.alt_instru.getValue()/100))*100))));
  1491. if(me.input.alt_instru.getValue()>0){
  1492. me.hundred_feet_Alt.setText(sprintf("%d",abs(int((me.input.alt_instru.getValue()/100)))));
  1493. }else{
  1494. me.hundred_feet_Alt.setText(sprintf("-%d",abs(int((me.input.alt_instru.getValue()/100)))));
  1495. }
  1496. me.speedAltGroup.update();
  1497. },
  1498. display_radarAltimeter:func(){
  1499. if( me.input.rad_alt.getValue() < 5000) { #Or be selected be a special swith not yet done # Only show below 5000AGL
  1500. if(abs(me.input.pitch.getValue())<20 and abs(me.input.roll.getValue())<20){ #if the angle is above 20° the radar do not work
  1501. me.groundAlt.setText(sprintf("%4d", me.input.rad_alt.getValue()-8));#The radar should show 0 when on Ground
  1502. }else{
  1503. me.groundAlt.setText("*****");
  1504. }
  1505. me.groundAlt.show();
  1506. me.theH.show();
  1507. }else{
  1508. me.groundAlt.hide();
  1509. me.theH.hide();
  1510. }
  1511. },
  1512. display_inverted_T:func(){
  1513. if(me.input.gearPos.getValue()){
  1514. me.InvertedT.setTranslation(0, HudMath.getCenterPosFromDegs(0,-13)[1]);
  1515. me.InvertedT.show();
  1516. }else{
  1517. me.InvertedT.hide();
  1518. }
  1519. },
  1520. display_alpha:func(){
  1521. if(me.input.gearPos.getValue() < 1 and abs(me.input.alpha.getValue())>2 and me.input.MasterArm.getValue() == 0){
  1522. me.aoa.setText(sprintf("%0.1f",me.input.alpha.getValue()));
  1523. me.alphaGroup.show();
  1524. }else{
  1525. me.alphaGroup.hide();
  1526. }
  1527. },
  1528. display_gload:func(){
  1529. if(me.input.MasterArm.getValue()){
  1530. me.gload_Text.setText(sprintf("%0.1fG",me.input.gload.getValue()));
  1531. me.alpha_Text.setText(sprintf("%0.1fα",me.input.alpha.getValue()));
  1532. me.alphaGloadGroup.show();
  1533. }else{
  1534. me.alphaGloadGroup.hide();
  1535. }
  1536. },
  1537. display_loadsType:func{
  1538. if(me.input.MasterArm.getValue() and me.selectedWeap != nil){
  1539. # print(me.loads_hash[me.selectedWeap.type]);
  1540. me.loads_Type_text.setText(me.loads_hash[me.selectedWeap.type]);
  1541. me.loads_Type_text.show();
  1542. }else{
  1543. me.loads_Type_text.hide();
  1544. }
  1545. },
  1546. display_BulletCount:func{
  1547. if(me.input.MasterArm.getValue() and me.selectedWeap != nil){
  1548. # print("Test");
  1549. # print("Test:" ~ me.loads_hash[me.selectedWeap.type] ~ " : " ~ pylons.fcs.getAmmo());
  1550. # print("Test:" ~ me.selectedWeap.type ~ " : " ~ pylons.fcs.getAmmo());
  1551. if(me.selectedWeap.type == "30mm Cannon"){
  1552. # print(me.loads_hash[me.selectedWeap.type] ~ " : " ~ pylons.fcs.getAmmo());
  1553. me.Left_bullet_Count.setText(sprintf("%3d", pylons.fcs.getAmmo()/2));
  1554. me.Right_bullet_Count.setText(sprintf("%3d", pylons.fcs.getAmmo()/2));
  1555. me.bullet_CountGroup.show();
  1556. }else{
  1557. me.bullet_CountGroup.hide();
  1558. }
  1559. }else{
  1560. me.bullet_CountGroup.hide();
  1561. }
  1562. },
  1563. displaySelectedPylons:func{
  1564. #Init the vector
  1565. me.pylonRemainAmmo_hash = {
  1566. "L":0,
  1567. "C":0,
  1568. "R":0,
  1569. };
  1570. #Showing the circle around the L or R if the weapons is under the wings.
  1571. #A circle around a C is also done for center loads, but I couldn't find any docs on that, so it is conjecture
  1572. if(me.input.MasterArm.getValue() and me.selectedWeap != nil){
  1573. if(me.selectedWeap.type != "30mm Cannon"){
  1574. me.pylons_Group.show();
  1575. me.pylons_Circle_Group.show();
  1576. # print("Type:"~me.loads_hash[me.selectedWeap.type]);
  1577. # print("Pylons:"~pylons.fcs.getSelectedPylonNumber());
  1578. # print("Side:"~me.pylonsSide_hash[pylons.fcs.getSelectedPylonNumber()]);
  1579. #create the remainingAmmo vector and starting to count L and R
  1580. me.RemainingAmmoVector = pylons.fcs.getAllAmmo(pylons.fcs.getSelectedType());
  1581. for(i = 0 ; i < size(me.RemainingAmmoVector)-1 ; i += 1){
  1582. # print("NumPylons="~ i ~ " :"~me.RemainingAmmoVector[i]);
  1583. me.pylonRemainAmmo_hash[me.pylonsSide_hash[i]] += me.RemainingAmmoVector[i];
  1584. }
  1585. # print("Number Left Side :"~me.pylonRemainAmmo_hash["L"]);
  1586. # print("Number Right Side :"~me.pylonRemainAmmo_hash["R"]);
  1587. #Showing the pylon
  1588. if(me.pylonRemainAmmo_hash["L"]>0){me.Left_pylons.show();}else{me.Left_pylons.hide();}
  1589. if(me.pylonRemainAmmo_hash["C"]>0){me.Center_pylons.show();}else{me.Center_pylons.hide();}
  1590. if(me.pylonRemainAmmo_hash["R"]>0){me.Right_pylons.show();}else{me.Right_pylons.hide();}
  1591. #Showing the Circle for the selected pylon
  1592. if(me.pylonsSide_hash[pylons.fcs.getSelectedPylonNumber()] == "L"){me.LeftCircle.show();}else{me.LeftCircle.hide();}
  1593. if(me.pylonsSide_hash[pylons.fcs.getSelectedPylonNumber()] == "C"){me.CenterCircle.show();}else{me.CenterCircle.hide();}
  1594. if(me.pylonsSide_hash[pylons.fcs.getSelectedPylonNumber()] == "R"){me.RightCircle.show();}else{me.RightCircle.hide();}
  1595. }else{
  1596. me.pylons_Group.hide();
  1597. me.pylons_Circle_Group.hide();
  1598. }
  1599. }else{
  1600. me.pylons_Group.hide();
  1601. me.pylons_Circle_Group.hide();
  1602. }
  1603. },
  1604. display_Waypoint:func(coord,TEXT,NextNUM){
  1605. #coord is a geo object of the current destination
  1606. #TEXT is what will be written to describe our target : BE (Bullseye) ou DEST (route)
  1607. #NextNUM is the next waypoint/bullseye number (most of the time it's the waypoint number)
  1608. if(coord != nil){
  1609. if(me.aircraft_position.direct_distance_to(coord)*M2NM>10){
  1610. me.waypointDist.setText(sprintf("%d N",int(me.aircraft_position.direct_distance_to(coord)*M2NM)));
  1611. me.waypointDistSimple.setText(sprintf("%d N",int(me.aircraft_position.direct_distance_to(coord)*M2NM)));
  1612. }else{
  1613. me.waypointDist.setText(sprintf("%0.1f N",me.aircraft_position.direct_distance_to(coord)*M2NM));
  1614. me.waypointDistSimple.setText(sprintf("%0.1f N",me.aircraft_position.direct_distance_to(coord)*M2NM));
  1615. }
  1616. if(NextNUM != nil){
  1617. me.waypointNumber.setText(sprintf("%02d",NextNUM));
  1618. me.waypointNumberSimple.setText(sprintf("%02d",NextNUM));
  1619. }
  1620. me.DEST.setText(TEXT);
  1621. if(me.input.hdgDisplay.getValue()){
  1622. me.waypointHeading.setText(sprintf("%03d/",me.aircraft_position.course_to(coord)));
  1623. }else{
  1624. me.waypointHeading.setText(sprintf("%03d/",me.aircraft_position.course_to(coord)));
  1625. }
  1626. me.waypointGroupshow = 1;
  1627. }
  1628. },
  1629. displayHeattarget:func(c){
  1630. if(me.selectedWeap == nil or !me.input.MasterArm.getValue()){return 0;}
  1631. if(me.selectedWeap.type == "30mm Cannon"){return 0;}
  1632. if(me.selectedWeap.guidance == "heat" and me.selectedWeap.status == armament.MISSILE_LOCK){
  1633. #show triangle if IR missile have a lock (but don't show if it's a radar lock)
  1634. #screen.log.write("me.selectedWeap.class:"~ me.selectedWeap.class, 1.0, 1.0, 0.0);
  1635. #screen.log.write("me.selectedWeap.guidance:"~ me.selectedWeap.guidance, 1.0, 1.0, 0.0);
  1636. if(me.selectedWeap.Tgt == nil){return 0;}
  1637. if(c.get_Callsign() != me.selectedWeap.Tgt.get_Callsign()){return 0;}
  1638. screen.log.write("me.selectedWeap.Tgt.get_Callsign():"~ me.selectedWeap.Tgt.get_Callsign(), 1.0, 1.0, 0.0);
  1639. return 1;
  1640. #Should now display the triangle group
  1641. # me.TriangleGroupe.show();
  1642. # me.triangle.setTranslation(triPos);
  1643. # me.triangle2.setTranslation(triPos);
  1644. }else{return 0;}
  1645. },
  1646. displayRectangletarget:func(c,i){
  1647. #if(me.selectedWeap == nil or !me.input.MasterArm.getValue()){return 0;}
  1648. #if(me.selectedWeap.type == "30mm Cannon"){return 0;}
  1649. #if(me.selectedWeap.guidance == "heat" and me.selectedWeap.status == armament.MISSILE_LOCK){
  1650. if(i<size(me.targetArray) and size(me.raw_list)>0 and c.objectDisplay ==1 ){
  1651. if(c.get_Callsign() == me.closestCallsign and me.closestRange > 0){
  1652. #screen.log.write("me.selectedWeap.Tgt.get_Callsign():"~ me.selectedWeap.Tgt.get_Callsign(), 1.0, 1.0, 0.0);
  1653. return 1;
  1654. }
  1655. }
  1656. return 0;
  1657. },
  1658. displayTarget:func(){
  1659. #To put a triangle on the selected target
  1660. #This should be changed by calling directly the radar object (in case of multi targeting)
  1661. #Getting the radar target from radar tgts_list
  1662. if(mirage2000.myRadar3.tgts_list != nil and size(mirage2000.myRadar3.tgts_list)>mirage2000.myRadar3.Target_Index){
  1663. me.MytargetIndex = mirage2000.myRadar3.Target_Index;
  1664. me.closestCallsign = me.MytargetIndex != -1 ? mirage2000.myRadar3.tgts_list[me.MytargetIndex].get_Callsign():"";
  1665. me.is_Painted = me.MytargetIndex != -1 ? mirage2000.myRadar3.tgts_list[me.MytargetIndex].isPainted():0;
  1666. me.closestRange = me.MytargetIndex != -1 ? mirage2000.myRadar3.targetRange(mirage2000.myRadar3.tgts_list[me.MytargetIndex]):0;
  1667. }else{
  1668. me.closestCallsign = "";
  1669. me.closestRange = -1;
  1670. }
  1671. me.showdistanceToken = 0;
  1672. me.raw_list = mirage2000.myRadar3.ContactsList;
  1673. i = 0;
  1674. me.designatedDistanceFT = nil;
  1675. foreach(var c; me.raw_list){
  1676. #This is too complicated :
  1677. #I need to change the way those things are displayed:
  1678. #list what should be displayed and make a fonction if it needs to be displayed
  1679. me.ShouldDisplayheat = me.displayHeattarget(c);
  1680. me.target_callsign = c.get_Callsign();
  1681. #print("Paint : " ~ me.target_callsign ~ " : "~ myTest);
  1682. #Position of the "target"
  1683. target_altitude = c.get_altitude();
  1684. target_heading_deg = c.get_heading();
  1685. target_Distance = c.get_range_from_Coord(me.aircraft_position);
  1686. var triPos = HudMath.getPosFromCoord(c.get_Coord());
  1687. #1- Show Rectangle : habe been painted (or selected ?)
  1688. #2- Show double triangle : IR missile LOCK without radar
  1689. #3- Show circle : the radar see it, without focusing
  1690. #4- Do not show anything : nothing see it
  1691. #Should this be displayed by a radar
  1692. #displayIt = c.objectDisplay;
  1693. #1 Rectangle :
  1694. if(me.displayRectangletarget(c,i)){
  1695. #Here for displaying the square (painting)
  1696. me.showdistanceToken = 1;
  1697. #Show square group
  1698. me.Square_Group.show();
  1699. me.Locked_Square.setTranslation(triPos);
  1700. me.Locked_Square_Dash.setTranslation(clamp(triPos[0],-me.MaxX*0.8,me.MaxX*0.8), clamp(triPos[1],-me.MaxY*0.8,me.MaxY*0.8));
  1701. #hide triangle and circle
  1702. me.TriangleGroupe.hide();
  1703. me.targetArray[i].hide();
  1704. me.distanceToTargetLineGroup.show();
  1705. me.displayDistanceToTargetLine(c);
  1706. if (math.abs(triPos[0])<2000 and math.abs(triPos[1])<2000) {#only show it when target is in front
  1707. me.designatedDistanceFT = c.get_Coord().direct_distance_to(geo.aircraft_position())*M2FT;
  1708. }
  1709. }elsif(me.displayHeattarget(c)) {
  1710. me.showdistanceToken = 1;
  1711. me.TriangleGroupe.show();
  1712. me.triangle.setTranslation(triPos);
  1713. me.triangle2.setTranslation(triPos);
  1714. #hide rectangle and circle
  1715. me.Square_Group.hide();
  1716. me.targetArray[i].hide();
  1717. if (math.abs(triPos[0])<2000 and math.abs(triPos[1])<2000) {#only show it when target is in front
  1718. me.designatedDistanceFT = c.get_Coord().direct_distance_to(geo.aircraft_position())*M2FT;
  1719. }
  1720. }elsif(c.objectDisplay == 1){
  1721. #show circle
  1722. me.targetArray[i].show();
  1723. me.targetArray[i].setTranslation(triPos);
  1724. }else{
  1725. #dont show anything
  1726. me.targetArray[i].hide();
  1727. }
  1728. #here is the text display : Normally not in the real HUD
  1729. if(c.objectDisplay == 1){
  1730. #here is the text display
  1731. me.TextInfoArray[i].show();
  1732. me.TextInfoArray[i].setTranslation(triPos[0]+19,triPos[1]);
  1733. me.TextInfoArray[i].setText(sprintf(" %s \n %.0f nm \n %d ft / %d", me.target_callsign, target_Distance, target_altitude, target_heading_deg));
  1734. }else{
  1735. me.targetArray[i].hide();
  1736. me.TextInfoArray[i].hide();
  1737. }
  1738. i+=1;
  1739. }
  1740. #The token has 1 when we have a selected target
  1741. #if we don't have target :
  1742. if(me.showdistanceToken == 0){
  1743. me.TriangleGroupe.hide();
  1744. me.Square_Group.hide();
  1745. me.distanceToTargetLineGroup.hide();
  1746. me.missileFireRange.hide();
  1747. }
  1748. for(var y=i;y<size(me.targetArray);y+=1){
  1749. me.targetArray[y].hide();
  1750. me.TextInfoArray[y].hide();
  1751. }
  1752. },
  1753. displayDistanceToTargetLine : func(contact){
  1754. me.MaxRadarRange = mirage2000.myRadar3.rangeTab[mirage2000.myRadar3.rangeIndex];
  1755. var myString ="";
  1756. #< 10 nm should be a float
  1757. #< 1000 m should be in meters
  1758. if(contact.get_range_from_Coord(me.aircraft_position)<= me.MaxRadarRange){
  1759. #Text for distance to target
  1760. if(contact.get_range_from_Coord(me.aircraft_position)*NM2M<1200){
  1761. myString = sprintf("%dm",contact.get_range_from_Coord(me.aircraft_position)*NM2M);
  1762. }elsif(contact.get_range_from_Coord(me.aircraft_position)<10){
  1763. myString = sprintf("%.1fnm",contact.get_range_from_Coord(me.aircraft_position));
  1764. }else{
  1765. myString = sprintf("%dnm",contact.get_range_from_Coord(me.aircraft_position));
  1766. }
  1767. if (me.displayDLZ(me.MaxRadarRange)){
  1768. me.missileFireRange.show();
  1769. }else{
  1770. me.missileFireRange.hide();
  1771. }
  1772. me.distanceToTargetLineChevronText.setText(myString);
  1773. me.distanceToTargetLineTextGroup.setTranslation(0,(me.distanceToTargetLineMax-me.distanceToTargetLineMin)-(contact.get_range_from_Coord(me.aircraft_position)*(me.distanceToTargetLineMax-me.distanceToTargetLineMin)/ me.MaxRadarRange)-100);
  1774. }
  1775. },
  1776. displayDLZ:func(){
  1777. if(me.selectedWeap != nil and me.input.MasterArm.getValue()){
  1778. #Testings
  1779. if(me.selectedWeap.type != "30mm Cannon"){
  1780. if(me.selectedWeap.class == "A" and me.selectedWeap.parents[0] == armament.AIM){
  1781. #Taking back the DLZ
  1782. me.myDLZ = pylons.getDLZ();
  1783. if(me.myDLZ != nil and size(me.myDLZ) == 5 and me.myDLZ[4]<me.myDLZ[0]*2){
  1784. #Max
  1785. me.MaxFireRange.setTranslation(0,clamp((me.distanceToTargetLineMax-me.distanceToTargetLineMin)-(me.myDLZ[0]*(me.distanceToTargetLineMax-me.distanceToTargetLineMin)/ me.MaxRadarRange)-100,me.distanceToTargetLineMin,me.distanceToTargetLineMax));
  1786. #MmiFireRange
  1787. me.MinFireRange.setTranslation(0,clamp((me.distanceToTargetLineMax-me.distanceToTargetLineMin)-(me.myDLZ[3]*(me.distanceToTargetLineMax-me.distanceToTargetLineMin)/ me.MaxRadarRange)-100,me.distanceToTargetLineMin,me.distanceToTargetLineMax));
  1788. #NEZFireRange
  1789. me.NEZFireRange.setTranslation(0,clamp((me.distanceToTargetLineMax-me.distanceToTargetLineMin)-(me.myDLZ[2]*(me.distanceToTargetLineMax-me.distanceToTargetLineMin)/ me.MaxRadarRange)-100,me.distanceToTargetLineMin,me.distanceToTargetLineMax));
  1790. me.missileFireRange.show();
  1791. return 1;
  1792. }
  1793. }elsif(me.selectedWeap.class == "GM" or me.selectedWeap.class == "M"){
  1794. me.MaxFireRange.setTranslation(0,clamp((me.distanceToTargetLineMax-me.distanceToTargetLineMin)-(me.selectedWeap.max_fire_range_nm*(me.distanceToTargetLineMax-me.distanceToTargetLineMin)/ me.MaxRadarRange)-100,me.distanceToTargetLineMin,me.distanceToTargetLineMax));
  1795. #MmiFireRange
  1796. me.MinFireRange.setTranslation(0,clamp((me.distanceToTargetLineMax-me.distanceToTargetLineMin)-(me.selectedWeap.min_fire_range_nm*(me.distanceToTargetLineMax-me.distanceToTargetLineMin)/ me.MaxRadarRange)-100,me.distanceToTargetLineMin,me.distanceToTargetLineMax));
  1797. me.NEZFireRange.hide();
  1798. me.MaxFireRange.show();
  1799. me.MinFireRange.show();
  1800. return 1;
  1801. }
  1802. }
  1803. }
  1804. return 0;
  1805. },
  1806. displayRunway:func(){
  1807. #var info = airportinfo(icao;
  1808. #Need to select the runways and write the conditions
  1809. #2. SYNTHETIC RUNWAY. The synthetic runway symbol is an aid for locating the real runway, especially during low visibility conditions.
  1810. #It is only visible when:
  1811. #a. The INS is on.
  1812. #b. The airport is the current fly-to waypoint.
  1813. #c. The runway data (heading and glideslope) were entered.
  1814. #d. Both localizer and glideslope have been captured
  1815. #e. The runway is less than 10 nautical miles away.
  1816. #f. Lateral deviation is less than 7º.
  1817. # The synthetic runway is removed from the HUD as soon as there is weight on the landing gear’s wheels.
  1818. #print("reciprocal:" , info.runways[rwy].reciprocal, " ICAO:", info.id, " runway:",info.runways[rwy].id);
  1819. #Calculating GPS coord of the runway's corners
  1820. #No need to recalculate GPS position everytime, only when the destination airport is changed
  1821. if(me.RunwayCoord.lat != me.info.runways[me.selectedRunway].lat or me.RunwayCoord.lpn != me.info.runways[me.selectedRunway].lon){
  1822. me.RunwayCoord.set_latlon(me.info.runways[me.selectedRunway].lat, me.info.runways[me.selectedRunway].lon, me.info.elevation);
  1823. me.RunwaysCoordCornerLeft.set_latlon(me.info.runways[me.selectedRunway].lat, me.info.runways[me.selectedRunway].lon, me.info.elevation);
  1824. me.RunwaysCoordCornerLeft.apply_course_distance((me.info.runways[me.selectedRunway].heading)-90,(me.info.runways[me.selectedRunway].width)/2);
  1825. me.RunwaysCoordCornerRight.set_latlon(me.info.runways[me.selectedRunway].lat, me.info.runways[me.selectedRunway].lon, me.info.elevation);
  1826. me.RunwaysCoordCornerRight.apply_course_distance((me.info.runways[me.selectedRunway].heading)+90,(me.info.runways[me.selectedRunway].width)/2);
  1827. me.RunwaysCoordEndCornerLeft.set_latlon(me.info.runways[me.selectedRunway].lat, me.info.runways[me.selectedRunway].lon, me.info.elevation);
  1828. me.RunwaysCoordEndCornerLeft.apply_course_distance((me.info.runways[me.selectedRunway].heading)-90,(me.info.runways[me.selectedRunway].width)/2);
  1829. me.RunwaysCoordEndCornerLeft.apply_course_distance((me.info.runways[me.selectedRunway].heading),me.info.runways[me.selectedRunway].length);
  1830. me.RunwaysCoordEndCornerRight.set_latlon(me.info.runways[me.selectedRunway].lat, me.info.runways[me.selectedRunway].lon, me.info.elevation);
  1831. me.RunwaysCoordEndCornerRight.apply_course_distance((me.info.runways[me.selectedRunway].heading)+90,(me.info.runways[me.selectedRunway].width)/2);
  1832. me.RunwaysCoordEndCornerRight.apply_course_distance((me.info.runways[me.selectedRunway].heading),me.info.runways[me.selectedRunway].length);
  1833. }
  1834. #Calculating the HUD coord of the runways coord
  1835. me.MyRunwayTripos = HudMath.getPosFromCoord(me.RunwayCoord);
  1836. me.MyRunwayCoordCornerLeftTripos = HudMath.getPosFromCoord(me.RunwaysCoordCornerLeft);
  1837. me.MyRunwayCoordCornerRightTripos = HudMath.getPosFromCoord(me.RunwaysCoordCornerRight);
  1838. me.MyRunwayCoordCornerEndLeftTripos = HudMath.getPosFromCoord(me.RunwaysCoordEndCornerLeft);
  1839. me.MyRunwayCoordCornerEndRightTripos = HudMath.getPosFromCoord(me.RunwaysCoordEndCornerRight);
  1840. #Updating : clear all previous stuff
  1841. me.myRunwayGroup.removeAllChildren();
  1842. #drawing the runway
  1843. me.RunwaysDrawing = me.myRunwayGroup.createChild("path")
  1844. .setColor(me.myGreen)
  1845. .moveTo(me.MyRunwayCoordCornerLeftTripos[0],me.MyRunwayCoordCornerLeftTripos[1])
  1846. .lineTo(me.MyRunwayCoordCornerRightTripos[0],me.MyRunwayCoordCornerRightTripos[1])
  1847. .lineTo(me.MyRunwayCoordCornerEndRightTripos[0],me.MyRunwayCoordCornerEndRightTripos[1])
  1848. .lineTo(me.MyRunwayCoordCornerEndLeftTripos[0],me.MyRunwayCoordCornerEndLeftTripos[1])
  1849. .lineTo(me.MyRunwayCoordCornerLeftTripos[0],me.MyRunwayCoordCornerLeftTripos[1])
  1850. .setStrokeLineWidth(4);
  1851. me.myRunwayGroup.update();
  1852. },
  1853. displayBoreCross:func(){
  1854. #maybe it should be a different cross.
  1855. if(me.input.MasterArm.getValue() and pylons.fcs.getSelectedWeapon() !=nil){
  1856. if(me.selectedWeap.type == "30mm Cannon"){#if weapons selected
  1857. me.boreCross.setTranslation(HudMath.getBorePos());
  1858. me.boreCross.show();
  1859. }else{
  1860. me.boreCross.hide();
  1861. }
  1862. }else{
  1863. me.boreCross.hide();
  1864. }
  1865. },
  1866. #This should be called with a geo.coord object.
  1867. #Doing that way it could be used for waypoint, bullseye and ground target
  1868. # if(me.input.distNextWay.getValue()!= nil and me.input.distNextWay.getValue()<10 and me.input.gearPos.getValue() == 0
  1869. # and me.input.NextWayNum.getValue()!=-1 and me.NXTWP != nil and me.fp.currentWP() != nil){#if waypoint is active
  1870. displayWaypointCross:func(coord){
  1871. #print("runing displayWaypointCross");
  1872. if(coord != nil){ #The aircraft should be flying ... This need to be done before in hud mode selection
  1873. #print("coord is not nil");
  1874. if(me.aircraft_position.direct_distance_to(coord)*M2NM<10){
  1875. #print("Shoud display the waypoint");
  1876. me.WaypointCross.setTranslation(HudMath.getPosFromCoord(coord));
  1877. me.displayWaypointCrossShow = 1;
  1878. return;
  1879. }
  1880. }
  1881. #me.WaypointCross.hide();
  1882. },
  1883. #This should be called at every iteration
  1884. NextWaypointCoordinate:func(){
  1885. if(me.fp.currentWP() != nil){
  1886. #Sometime you can set up an altitude to your waypoint. if it's the case we take it.
  1887. me.NxtElevation = getprop("/autopilot/route-manager/route/wp[" ~ me.input.currentWp.getValue() ~ "]/altitude-m");
  1888. #print("me.NxtWP_latDeg:",me.NxtWP_latDeg, " me.NxtWP_lonDeg:",me.NxtWP_lonDeg);
  1889. #if the altitude isn't set, just take the ground alt.
  1890. var Geo_Elevation = geo.elevation(me.fp.currentWP().lat , me.fp.currentWP().lon);
  1891. Geo_Elevation = Geo_Elevation == nil ? 0: Geo_Elevation;
  1892. #print("Geo_Elevation:",Geo_Elevation," me.NxtElevation:",me.NxtElevation);
  1893. #if no altitude, then take ground alt
  1894. if( me.NxtElevation != nil){
  1895. Geo_Elevation = me.NxtElevation > Geo_Elevation ? me.NxtElevation : Geo_Elevation ;
  1896. me.NXTWP.set_latlon(me.fp.currentWP().lat , me.fp.currentWP().lon , Geo_Elevation + 2);
  1897. }
  1898. }
  1899. },
  1900. resetGunPos: func {
  1901. me.gunPos = [];
  1902. for(i = 0;i < me.funnelParts*4;i+=1){
  1903. var tmp = [];
  1904. for(var myloopy = 0;myloopy <= i+1;myloopy+=1){
  1905. append(tmp,nil);
  1906. }
  1907. append(me.gunPos, tmp);
  1908. }
  1909. },
  1910. makeVector: func (siz,content) {
  1911. var vec = setsize([],siz*4);
  1912. var k = 0;
  1913. while(k<siz*4) {
  1914. vec[k] = content;
  1915. k += 1;
  1916. }
  1917. return vec;
  1918. },
  1919. displayEEGS: func() {
  1920. #note: this stuff is expensive like hell to compute, but..lets do it anyway.
  1921. #var me.funnelParts = 40;#max 10
  1922. var st = systime();
  1923. me.eegsMe.dt = st-me.lastTime;
  1924. if (me.eegsMe.dt > me.averageDt*3) {
  1925. me.lastTime = st;
  1926. me.resetGunPos();
  1927. me.eegsGroup.removeAllChildren();
  1928. } else {
  1929. #printf("dt %05.3f",me.eegsMe.dt);
  1930. me.lastTime = st;
  1931. me.eegsMe.hdg = me.input.hdgReal.getValue();
  1932. me.eegsMe.pitch = me.input.pitch.getValue();
  1933. me.eegsMe.roll = me.input.roll.getValue();
  1934. var hdp = {roll:me.eegsMe.roll,current_view_z_offset_m: me.input.z_offset_m.getValue()};
  1935. me.eegsMe.ac = geo.aircraft_position();
  1936. me.eegsMe.allow = 1;
  1937. me.drawEEGSPipper = 0;
  1938. me.drawEEGS300 = 0;
  1939. me.drawEEGS600 = 0;
  1940. me.strfRange = 4500 * M2FT;
  1941. if(me.strf or me.hydra) {
  1942. me.groundDistanceFT = nil;
  1943. var l = 0;
  1944. for (l = 0;l < me.funnelParts*4;l+=1) {
  1945. # compute display positions of funnel on hud
  1946. var pos = me.gunPos[l][0];
  1947. if (pos == nil) {
  1948. me.eegsMe.allow = 0;
  1949. } else {
  1950. var ac = me.gunPos[l][0][1];
  1951. pos = me.gunPos[l][0][0];
  1952. var el = geo.elevation(pos.lat(),pos.lon());
  1953. if (el == nil) {
  1954. el = 0;
  1955. }
  1956. if (l != 0 and el > pos.alt()) {
  1957. var hitPos = geo.Coord.new(pos);
  1958. hitPos.set_alt(el);
  1959. me.groundDistanceFT = (el-pos.alt())*M2FT;#ac.direct_distance_to(hitPos)*M2FT;
  1960. me.strfRange = hitPos.direct_distance_to(me.eegsMe.ac)*M2FT;
  1961. l = l;
  1962. break;
  1963. }
  1964. }
  1965. }
  1966. #print("me.eegsMe.allow:" ~ me.eegsMe.allow);
  1967. #print(" me.groundDistanceFT:"~ (me.groundDistanceFT==nil?"nil":me.groundDistanceFT));
  1968. # compute display positions of pipper on hud
  1969. if (me.eegsMe.allow and me.groundDistanceFT != nil) {
  1970. #print("test");
  1971. for (var ll = l-1;ll <= l;ll+=1) {
  1972. var ac = me.gunPos[ll][0][1];
  1973. var pos = me.gunPos[ll][0][0];
  1974. var pitch = me.gunPos[ll][0][2];
  1975. me.eegsMe.posTemp = HudMath.getPosFromCoord(pos,ac);
  1976. me.eegsMe.shellPosDist[ll] = ac.direct_distance_to(pos)*M2FT;
  1977. me.eegsMe.shellPosX[ll] = me.eegsMe.posTemp[0];#me.eegsMe.xcS;
  1978. me.eegsMe.shellPosY[ll] = me.eegsMe.posTemp[1];#me.eegsMe.ycS;
  1979. if (l == ll and me.strfRange*FT2M < 4500) {
  1980. var highdist = me.eegsMe.shellPosDist[ll];
  1981. var lowdist = me.eegsMe.shellPosDist[ll-1];
  1982. me.groundDistanceFT = me.groundDistanceFT/math.cos(90-pitch*D2R);
  1983. #me.groundDistanceFT = math.sqrt(me.groundDistanceFT*me.groundDistanceFT+me.groundDistanceFT*me.groundDistanceFT);#we just assume impact angle of 45 degs
  1984. me.eegsPipperX = HudMath.extrapolate(highdist-me.groundDistanceFT,lowdist,highdist,me.eegsMe.shellPosX[ll-1],me.eegsMe.shellPosX[ll]);
  1985. me.eegsPipperY = HudMath.extrapolate(highdist-me.groundDistanceFT,lowdist,highdist,me.eegsMe.shellPosY[ll-1],me.eegsMe.shellPosY[ll]);
  1986. me.drawEEGSPipper = 1;
  1987. #print("Should draw Piper");
  1988. }
  1989. }
  1990. }
  1991. }else{
  1992. for (var l = 0;l < me.funnelParts;l+=1) {
  1993. # compute display positions of funnel on hud
  1994. var pos = me.gunPos[l][l+1];
  1995. if (pos == nil) {
  1996. me.eegsMe.allow = 0;
  1997. } else {
  1998. var ac = me.gunPos[l][l][1];
  1999. pos = me.gunPos[l][l][0];
  2000. var ps = HudMath.getPosFromCoord(pos, ac);
  2001. me.eegsMe.xcS = ps[0];
  2002. me.eegsMe.ycS = ps[1];
  2003. me.eegsMe.shellPosDist[l] = ac.direct_distance_to(pos)*M2FT;
  2004. me.eegsMe.shellPosX[l] = me.eegsMe.xcS;
  2005. me.eegsMe.shellPosY[l] = me.eegsMe.ycS;
  2006. if (me.designatedDistanceFT != nil and !me.drawEEGSPipper) {
  2007. if (l != 0 and me.eegsMe.shellPosDist[l] >= me.designatedDistanceFT and me.eegsMe.shellPosDist[l]>me.eegsMe.shellPosDist[l-1]) {
  2008. var highdist = me.eegsMe.shellPosDist[l];
  2009. var lowdist = me.eegsMe.shellPosDist[l-1];
  2010. var fractionX = HudMath.extrapolate(me.designatedDistanceFT,lowdist,highdist,me.eegsMe.shellPosX[l-1],me.eegsMe.shellPosX[l]);
  2011. var fractionY = HudMath.extrapolate(me.designatedDistanceFT,lowdist,highdist,me.eegsMe.shellPosY[l-1],me.eegsMe.shellPosY[l]);
  2012. me.eegsRightX[0] = fractionX;
  2013. me.eegsRightY[0] = fractionY;
  2014. me.drawEEGSPipper = 1;
  2015. }
  2016. }
  2017. if (!me.drawEEGS300) {
  2018. if (l != 0 and me.eegsMe.shellPosDist[l] >= 300*M2FT and me.eegsMe.shellPosDist[l]>me.eegsMe.shellPosDist[l-1]) {
  2019. var highdist = me.eegsMe.shellPosDist[l];
  2020. var lowdist = me.eegsMe.shellPosDist[l-1];
  2021. var fractionX = HudMath.extrapolate(300*M2FT,lowdist,highdist,me.eegsMe.shellPosX[l-1],me.eegsMe.shellPosX[l]);
  2022. var fractionY = HudMath.extrapolate(300*M2FT,lowdist,highdist,me.eegsMe.shellPosY[l-1],me.eegsMe.shellPosY[l]);
  2023. me.eegsRightX[1] = fractionX;
  2024. me.eegsRightY[1] = fractionY;
  2025. me.drawEEGS300 = 1;
  2026. }
  2027. }
  2028. if (!me.drawEEGS600) {
  2029. if (l != 0 and me.eegsMe.shellPosDist[l] >= 600*M2FT and me.eegsMe.shellPosDist[l]>me.eegsMe.shellPosDist[l-1]) {
  2030. var highdist = me.eegsMe.shellPosDist[l];
  2031. var lowdist = me.eegsMe.shellPosDist[l-1];
  2032. var fractionX = HudMath.extrapolate(600*M2FT,lowdist,highdist,me.eegsMe.shellPosX[l-1],me.eegsMe.shellPosX[l]);
  2033. var fractionY = HudMath.extrapolate(600*M2FT,lowdist,highdist,me.eegsMe.shellPosY[l-1],me.eegsMe.shellPosY[l]);
  2034. me.eegsRightX[2] = fractionX;
  2035. me.eegsRightY[2] = fractionY;
  2036. me.drawEEGS600 = 1;
  2037. }
  2038. }
  2039. }
  2040. }
  2041. }
  2042. if (me.eegsMe.allow and !(me.strf or me.hydra)) {
  2043. # draw the funnel
  2044. for (var k = 0;k<me.funnelParts;k+=1) {
  2045. me.eegsLeftX[k] = me.eegsMe.shellPosX[k];
  2046. me.eegsLeftY[k] = me.eegsMe.shellPosY[k];
  2047. }
  2048. me.eegsGroup.removeAllChildren();
  2049. for (var i = 0; i < me.funnelParts-1; i+=1) {
  2050. me.fnnl = me.eegsGroup.createChild("path")
  2051. .setColor(me.myGreen)
  2052. .moveTo(me.eegsLeftX[i], me.eegsLeftY[i])
  2053. .lineTo(me.eegsLeftX[i+1], me.eegsLeftY[i+1])
  2054. .setStrokeLineWidth(4);
  2055. if (i==0) {
  2056. me.fnnl.setStrokeDashArray([5,5]);
  2057. }
  2058. }
  2059. if (me.drawEEGSPipper) {
  2060. me.EEGSdeg = math.max(0,HudMath.extrapolate(me.designatedDistanceFT*FT2M,1200,300,360,0))*D2R;
  2061. me.EEGSdegPos = [math.sin(me.EEGSdeg)*40,40-math.cos(me.EEGSdeg)*40];
  2062. #drawing mini and centra point
  2063. me.eegsGroup.createChild("path")
  2064. .moveTo(me.eegsRightX[0],me.eegsRightY[0])
  2065. .lineTo(me.eegsRightX[0],me.eegsRightY[0])
  2066. .moveTo(me.eegsRightX[0], me.eegsRightY[0]-40)
  2067. .lineTo(me.eegsRightX[0], me.eegsRightY[0]-55)
  2068. .moveTo(me.eegsRightX[0], me.eegsRightY[0]+40)
  2069. .lineTo(me.eegsRightX[0], me.eegsRightY[0]+55)
  2070. .moveTo(me.eegsRightX[0]-40, me.eegsRightY[0])
  2071. .lineTo(me.eegsRightX[0]-55, me.eegsRightY[0])
  2072. .moveTo(me.eegsRightX[0]+40, me.eegsRightY[0])
  2073. .lineTo(me.eegsRightX[0]+55, me.eegsRightY[0])
  2074. .setColor(me.myGreen)
  2075. .setStrokeLineWidth(4);
  2076. #drawing mini and centra point
  2077. if(me.designatedDistanceFT*FT2M <1200){
  2078. me.eegsGroup.createChild("path")
  2079. .moveTo(me.eegsRightX[0],me.eegsRightY[0]-40)
  2080. .lineTo(me.eegsRightX[0], me.eegsRightY[0]-55)
  2081. .setCenter(me.eegsRightX[0],me.eegsRightY[0])
  2082. .setColor(me.myGreen)
  2083. .setStrokeLineWidth(4)
  2084. .setRotation(me.EEGSdeg);
  2085. }
  2086. if (me.EEGSdeg<180*D2R) {
  2087. me.eegsGroup.createChild("path")
  2088. .setColor(me.myGreen)
  2089. .moveTo(me.eegsRightX[0], me.eegsRightY[0]-40)
  2090. .arcSmallCW(40,40,0,me.EEGSdegPos[0],me.EEGSdegPos[1])
  2091. .setStrokeLineWidth(4);
  2092. } elsif (me.EEGSdeg>=360*D2R) {
  2093. me.eegsGroup.createChild("path")
  2094. .setColor(me.myGreen)
  2095. .moveTo(me.eegsRightX[0], me.eegsRightY[0]-40)
  2096. .arcSmallCW(40,40,0,0,80)
  2097. .arcSmallCW(40,40,0,0,-80)
  2098. .setStrokeLineWidth(4);
  2099. } else {
  2100. me.eegsGroup.createChild("path")
  2101. .setColor(me.myGreen)
  2102. .moveTo(me.eegsRightX[0], me.eegsRightY[0]-40)
  2103. .arcLargeCW(40,40,0,me.EEGSdegPos[0],me.EEGSdegPos[1])
  2104. .setStrokeLineWidth(4);
  2105. }
  2106. }
  2107. if (me.drawEEGS300 and !me.drawEEGSPipper) {
  2108. var halfspan = math.atan2(me.wingspanFT*0.5,300*M2FT)*R2D*HudMath.getPixelPerDegreeAvg(2.0);#35ft average fighter wingspan
  2109. me.eegsGroup.createChild("path")
  2110. .setColor(me.myGreen)
  2111. .moveTo(me.eegsRightX[1]-halfspan, me.eegsRightY[1])
  2112. .horiz(halfspan*2)
  2113. .setStrokeLineWidth(4);
  2114. }
  2115. if (me.drawEEGS600 and !me.drawEEGSPipper) {
  2116. var halfspan = math.atan2(me.wingspanFT*0.5,600*M2FT)*R2D*HudMath.getPixelPerDegreeAvg(2.0);#35ft average fighter wingspan
  2117. me.eegsGroup.createChild("path")
  2118. .setColor(me.myGreen)
  2119. .moveTo(me.eegsRightX[2]-halfspan, me.eegsRightY[2])
  2120. .horiz(halfspan*2)
  2121. .setStrokeLineWidth(4);
  2122. }
  2123. me.eegsGroup.update();
  2124. }
  2125. #print("me.strfRange in meters:" ~me.strfRange*FT2M);
  2126. #Same Piper asthe A/A it should be done in a function
  2127. if (me.eegsMe.allow and (me.strf or me.hydra)) {
  2128. me.eegsGroup.removeAllChildren();
  2129. if (me.drawEEGSPipper and me.strfRange*FT2M <= 4000) {
  2130. #print("me.strfRange in meters:" ~me.strfRange*FT2M);
  2131. me.EEGSdeg = math.max(0,HudMath.extrapolate(me.strfRange*FT2M,2400,600,360,0))*D2R;
  2132. me.EEGSdegPos = [math.sin(me.EEGSdeg)*40,40-math.cos(me.EEGSdeg)*40];
  2133. #drawing mini line and centra point
  2134. me.eegsGroup.createChild("path")
  2135. .moveTo(me.eegsPipperX,me.eegsPipperY)
  2136. .lineTo(me.eegsPipperX,me.eegsPipperY)
  2137. .arcSmallCW(3, 3, 0, 3*2, 0)
  2138. .arcSmallCW(3, 3, 0, -3*2, 0)
  2139. .moveTo(me.eegsPipperX, me.eegsPipperY-40)
  2140. .lineTo(me.eegsPipperX, me.eegsPipperY-55)
  2141. .moveTo(me.eegsPipperX, me.eegsPipperY+40)
  2142. .lineTo(me.eegsPipperX, me.eegsPipperY+55)
  2143. .moveTo(me.eegsPipperX-40, me.eegsPipperY)
  2144. .lineTo(me.eegsPipperX-55, me.eegsPipperY)
  2145. .moveTo(me.eegsPipperX+40, me.eegsPipperY)
  2146. .lineTo(me.eegsPipperX+55, me.eegsPipperY)
  2147. .setColor(me.myGreen)
  2148. .setStrokeLineWidth(4);
  2149. # Distance to target
  2150. me.eegsGroup.createChild("text")
  2151. .setColor(me.myGreen)
  2152. .setTranslation(me.maxladderspan,-120)
  2153. .setDouble("character-size", 35)
  2154. .setAlignment("left-center")
  2155. .setText(sprintf("%.1f KM", me.strfRange*FT2M/1000));
  2156. #drawing piper
  2157. if(me.strfRange*FT2M <4000){
  2158. me.eegsGroup.createChild("path")
  2159. .moveTo(me.eegsPipperX,me.eegsPipperY-40)
  2160. .lineTo(me.eegsPipperX, me.eegsPipperY-55)
  2161. .setCenter(me.eegsPipperX,me.eegsPipperY)
  2162. .setColor(me.myGreen)
  2163. .setStrokeLineWidth(4)
  2164. .setRotation(me.EEGSdeg);
  2165. }
  2166. if (me.EEGSdeg<180*D2R) {
  2167. me.eegsGroup.createChild("path")
  2168. .setColor(me.myGreen)
  2169. .moveTo(me.eegsPipperX, me.eegsPipperY-40)
  2170. .arcSmallCW(40,40,0,me.EEGSdegPos[0],me.EEGSdegPos[1])
  2171. .setStrokeLineWidth(4);
  2172. } elsif (me.EEGSdeg>=360*D2R) {
  2173. me.eegsGroup.createChild("path")
  2174. .setColor(me.myGreen)
  2175. .moveTo(me.eegsPipperX, me.eegsPipperY-40)
  2176. .arcSmallCW(40,40,0,0,80)
  2177. .arcSmallCW(40,40,0,0,-80)
  2178. .setStrokeLineWidth(4);
  2179. } else {
  2180. me.eegsGroup.createChild("path")
  2181. .setColor(me.myGreen)
  2182. .moveTo(me.eegsPipperX, me.eegsPipperY-40)
  2183. .arcLargeCW(40,40,0,me.EEGSdegPos[0],me.EEGSdegPos[1])
  2184. .setStrokeLineWidth(4);
  2185. }
  2186. #var mr = 0.4 * 1.5;
  2187. # var mr = 1.8;
  2188. # var pipperRadius = 15 * mr;
  2189. # if (me.strfRange <= 4000) {
  2190. # me.eegsGroup.createChild("path")
  2191. # .moveTo(me.eegsPipperX-pipperRadius, me.eegsPipperY-pipperRadius-2)
  2192. # .horiz(pipperRadius*2)
  2193. # .moveTo(me.eegsPipperX-pipperRadius, me.eegsPipperY)
  2194. # .arcSmallCW(pipperRadius, pipperRadius, 0, pipperRadius*2, 0)
  2195. # .arcSmallCW(pipperRadius, pipperRadius, 0, -pipperRadius*2, 0)
  2196. # .moveTo(me.eegsPipperX-2*mr,me.eegsPipperY)
  2197. # .arcSmallCW(2*mr,2*mr, 0, 2*mr*2, 0)
  2198. # .arcSmallCW(2*mr,2*mr, 0, -2*mr*2, 0)
  2199. # .setStrokeLineWidth(4)
  2200. # .setColor(me.myGreen);
  2201. # } else {
  2202. # me.eegsGroup.createChild("path")
  2203. # .moveTo(me.eegsPipperX-pipperRadius, me.eegsPipperY)
  2204. # .arcSmallCW(pipperRadius, pipperRadius, 0, pipperRadius*2, 0)
  2205. # .arcSmallCW(pipperRadius, pipperRadius, 0, -pipperRadius*2, 0)
  2206. # .moveTo(me.eegsPipperX-2*mr,me.eegsPipperY)
  2207. # .arcSmallCW(2*mr,2*mr, 0, 2*mr*2, 0)
  2208. # .arcSmallCW(2*mr,2*mr, 0, -2*mr*2, 0)
  2209. # .setStrokeLineWidth(4)
  2210. # .setColor(me.myGreen);
  2211. # }
  2212. }
  2213. me.eegsGroup.update();
  2214. }
  2215. #calc shell positions
  2216. me.eegsMe.vel = me.input.uBody_fps.getValue() +3363.0 ; #3363.0 = speed
  2217. me.eegsMe.geodPos = aircraftToCart({x:-0, y:0, z: me.input.y_offset_m.getValue()});#position (meters) of gun in aircraft (x and z inverted)
  2218. me.eegsMe.eegsPos.set_xyz(me.eegsMe.geodPos.x, me.eegsMe.geodPos.y, me.eegsMe.geodPos.z);
  2219. me.eegsMe.altC = me.eegsMe.eegsPos.alt();
  2220. me.eegsMe.rs = armament.AIM.rho_sndspeed(me.eegsMe.altC*M2FT);#simplified
  2221. me.eegsMe.rho = me.eegsMe.rs[0];
  2222. me.eegsMe.mass = 0.9369635/ armament.slugs_to_lbm;#0.9369635=lbs
  2223. #print("x,y");
  2224. #printf("%d,%d",0,0);
  2225. #print("-----");
  2226. var multi = (me.strf or me.hydra)?4:1;
  2227. for (var j = 0;j < me.funnelParts*multi;j+=1) {
  2228. #calc new speed
  2229. me.eegsMe.Cd = drag(me.eegsMe.vel/ me.eegsMe.rs[1],0.193);#0.193=cd
  2230. me.eegsMe.q = 0.5 * me.eegsMe.rho * me.eegsMe.vel * me.eegsMe.vel;
  2231. me.eegsMe.deacc = (me.eegsMe.Cd * me.eegsMe.q * 0.007609) / me.eegsMe.mass;#0.007609=eda
  2232. me.eegsMe.vel -= me.eegsMe.deacc * me.averageDt;
  2233. me.eegsMe.speed_down_fps = -math.sin(me.eegsMe.pitch * D2R) * (me.eegsMe.vel);
  2234. me.eegsMe.speed_horizontal_fps = math.cos(me.eegsMe.pitch * D2R) * (me.eegsMe.vel);
  2235. me.eegsMe.speed_down_fps += 9.81 *M2FT *me.averageDt;
  2236. me.eegsMe.altC -= (me.eegsMe.speed_down_fps*me.averageDt)*FT2M;
  2237. me.eegsMe.dist = (me.eegsMe.speed_horizontal_fps*me.averageDt)*FT2M;
  2238. me.eegsMe.eegsPos.apply_course_distance(me.eegsMe.hdg, me.eegsMe.dist);
  2239. me.eegsMe.eegsPos.set_alt(me.eegsMe.altC);
  2240. me.old = me.gunPos[j];
  2241. me.gunPos[j] = [[geo.Coord.new(me.eegsMe.eegsPos),me.eegsMe.ac, me.eegsMe.pitch]];
  2242. for (var m = 0;m<j+1;m+=1) {
  2243. append(me.gunPos[j], me.old[m]);
  2244. }
  2245. me.eegsMe.vel = math.sqrt(me.eegsMe.speed_down_fps*me.eegsMe.speed_down_fps+me.eegsMe.speed_horizontal_fps*me.eegsMe.speed_horizontal_fps);
  2246. me.eegsMe.pitch = math.atan2(-me.eegsMe.speed_down_fps,me.eegsMe.speed_horizontal_fps)*R2D;
  2247. }
  2248. }
  2249. me.eegsGroup.show();
  2250. },
  2251. isInCanvas:func(x,y){
  2252. #print("x:",x," y:",y," me.MaxX:",me.MaxX," MaxY",me.MaxY, " Result:",abs(x)<me.MaxX and abs(y)<me.MaxY;
  2253. return abs(x)<me.MaxX and abs(y)<me.MaxY;
  2254. },
  2255. ############## When pilot view is changed the whole scale need to be redrawn ##########################
  2256. recalculateLadder:func(){
  2257. me.LadderGroup.removeAllChildren();
  2258. for (var myladder = 5;myladder <= 90;myladder+=5)
  2259. {
  2260. if (myladder/10 == int(myladder/10)){
  2261. #Text bellow 0 left
  2262. me.LadderGroup.createChild("text")
  2263. .setColor(me.myGreen)
  2264. .setAlignment("right-center")
  2265. .setTranslation(-me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2266. .setDouble("character-size", 30)
  2267. .setText(myladder);
  2268. #Text bellow 0 left
  2269. me.LadderGroup.createChild("text")
  2270. .setColor(me.myGreen)
  2271. .setAlignment("left-center")
  2272. .setTranslation(me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2273. .setDouble("character-size", 30)
  2274. .setText(myladder);
  2275. #Text above 0 left
  2276. me.LadderGroup.createChild("text")
  2277. .setColor(me.myGreen)
  2278. .setAlignment("right-center")
  2279. .setTranslation(-me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*-myladder)
  2280. .setDouble("character-size", 30)
  2281. .setText(myladder);
  2282. #Text above 0 right
  2283. me.LadderGroup.createChild("text")
  2284. .setColor(me.myGreen)
  2285. .setAlignment("left-center")
  2286. .setTranslation(me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*-myladder)
  2287. .setDouble("character-size", 30)
  2288. .setText(myladder);
  2289. }
  2290. # ============= BELLOW 0 ===================
  2291. #half line bellow 0 (left part) ------------------
  2292. me.LadderGroup.createChild("path")
  2293. .setColor(me.myGreen)
  2294. .moveTo(-me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2295. .vert(-me.maxladderspan/15)
  2296. .setStrokeLineWidth(4);
  2297. me.LadderGroup.createChild("path")
  2298. .setColor(me.myGreen)
  2299. .moveTo(-me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2300. .horiz(me.maxladderspan*2/15)
  2301. .setStrokeLineWidth(4);
  2302. me.LadderGroup.createChild("path")
  2303. .setColor(me.myGreen)
  2304. .moveTo(-abs(me.maxladderspan - me.maxladderspan*2/15*2), HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2305. .horiz(me.maxladderspan*2/15)
  2306. .setStrokeLineWidth(4);
  2307. me.LadderGroup.createChild("path")
  2308. .setColor(me.myGreen)
  2309. .moveTo(-abs(me.maxladderspan - me.maxladderspan*2/15*4), HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2310. .horiz(me.maxladderspan*2/15)
  2311. .setStrokeLineWidth(4);
  2312. #half line (rigt part) ------------------
  2313. me.LadderGroup.createChild("path")
  2314. .setColor(me.myGreen)
  2315. .moveTo(me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2316. .vert(-me.maxladderspan/15)
  2317. .setStrokeLineWidth(4);
  2318. me.LadderGroup.createChild("path")
  2319. .setColor(me.myGreen)
  2320. .moveTo(me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2321. .horiz(-me.maxladderspan*2/15)
  2322. .setStrokeLineWidth(4);
  2323. me.LadderGroup.createChild("path")
  2324. .setColor(me.myGreen)
  2325. .moveTo(abs(me.maxladderspan - me.maxladderspan*2/15*2), HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2326. .horiz(-me.maxladderspan*2/15)
  2327. .setStrokeLineWidth(4);
  2328. me.LadderGroup.createChild("path")
  2329. .setColor(me.myGreen)
  2330. .moveTo(abs(me.maxladderspan - me.maxladderspan*2/15*4), HudMath.getPixelPerDegreeAvg(me.ladderScale)*myladder)
  2331. .horiz(-me.maxladderspan*2/15)
  2332. .setStrokeLineWidth(4);
  2333. # ============= ABOVE 0 ===================
  2334. me.LadderGroup.createChild("path")
  2335. .setColor(me.myGreen)
  2336. .moveTo(-me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*-myladder)
  2337. .vert(me.maxladderspan/15)
  2338. .setStrokeLineWidth(4);
  2339. me.LadderGroup.createChild("path")
  2340. .setColor(me.myGreen)
  2341. .moveTo(-me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*-myladder)
  2342. .horiz(me.maxladderspan/3*2)
  2343. .setStrokeLineWidth(4);
  2344. #half line (rigt part) ------------------
  2345. me.LadderGroup.createChild("path")
  2346. .setColor(me.myGreen)
  2347. .moveTo(me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*-myladder)
  2348. .horiz(-me.maxladderspan/3*2)
  2349. .setStrokeLineWidth(4);
  2350. me.LadderGroup.createChild("path")
  2351. .setColor(me.myGreen)
  2352. .moveTo(me.maxladderspan, HudMath.getPixelPerDegreeAvg(me.ladderScale)*-myladder)
  2353. .vert(me.maxladderspan/15)
  2354. .setStrokeLineWidth(4);
  2355. }
  2356. },
  2357. interpolate: func (start, end, fraction) {
  2358. me.xx = (start.x()*(1-fraction)
  2359. +end.x()*fraction);
  2360. me.yy = (start.y()*(1-fraction)+end.y()*fraction);
  2361. me.zz = (start.z()*(1-fraction)+end.z()*fraction);
  2362. me.cc = geo.Coord.new();
  2363. me.cc.set_xyz(me.xx,me.yy,me.zz);
  2364. return me.cc;
  2365. },
  2366. };
  2367. #var init = setlistener("/sim/signals/fdm-initialized", func() {
  2368. # removelistener(init); # only call once
  2369. # var hud_pilot = HUD.new({"node": "canvasHUD", "texture": "hud.png"});
  2370. # hud_pilot.update();
  2371. # var hud_copilot = HUD.new({"node": "verre2"});
  2372. # hud_copilot.update();
  2373. #});
  2374. #var initcanvas = func() {
  2375. # var hud_pilot = HUD.new({"node": "canvasHUD", "texture": "hud.png"});
  2376. # hud_pilot.update();
  2377. #var hud_copilot = HUD.new({"node": "verre2"});
  2378. #hud_copilot.update()
  2379. #};
  2380. var drag = func (Mach, _cd) {
  2381. if (Mach < 0.7)
  2382. return 0.0125 * Mach + _cd;
  2383. elsif (Mach < 1.2)
  2384. return 0.3742 * math.pow(Mach, 2) - 0.252 * Mach + 0.0021 + _cd;
  2385. else
  2386. return 0.2965 * math.pow(Mach, -1.1506) + _cd;
  2387. };
  2388. var deviation_normdeg = func(our_heading, target_bearing) {
  2389. var dev_norm = target_bearing-our_heading;
  2390. dev_norm=geo.normdeg180(dev_norm);
  2391. return dev_norm;
  2392. };