]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIStorm.cxx
15d8c4fe395747cfb51fcd070b9c7259c5845aea
[flightgear.git] / src / AIModel / AIStorm.cxx
1 // FGAIStorm - FGAIBase-derived class creates an AI thunderstorm or cloud
2 //
3 // Written by David Culp, started Feb 2004.
4 //
5 // Copyright (C) 2004  David P. Culp - davidculp2@comcast.net
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 #include <simgear/math/point3d.hxx>
26 #include <Main/fg_props.hxx>
27 #include <Main/globals.hxx>
28 #include <Scenery/scenery.hxx>
29 #include <string>
30 #include <math.h>
31 #include <cstdlib>
32
33 SG_USING_STD(string);
34
35 #include "AIStorm.hxx"
36
37
38 FGAIStorm::FGAIStorm(FGAIManager* mgr) {
39    manager = mgr;   
40    _type_str = "thunderstorm";
41    _otype = otStorm;
42    delay = 3.6;
43    subflashes = 1;
44    timer = 0.0;
45    random_delay = 3.6;
46    flash_node = fgGetNode("/environment/lightning/flash", true);
47    flash_node->setBoolValue(false);
48    flashed = 0; 
49    flashing = false;
50    subflash_index = -1;
51    subflash_array[0] =  1;
52    subflash_array[1] =  2;
53    subflash_array[2] =  1;
54    subflash_array[3] =  3;
55    subflash_array[4] =  2;
56    subflash_array[5] =  1;
57    subflash_array[6] =  1;
58    subflash_array[7] =  2;
59
60    turb_mag_node = fgGetNode("/environment/turbulence/magnitude-norm", true);
61    turb_rate_node = fgGetNode("/environment/turbulence/rate-hz", true);
62 }
63
64
65 FGAIStorm::~FGAIStorm() {
66 }
67
68
69 bool FGAIStorm::init() {
70    return FGAIBase::init();
71 }
72
73 void FGAIStorm::bind() {
74     FGAIBase::bind();
75 }
76
77 void FGAIStorm::unbind() {
78     FGAIBase::unbind();
79 }
80
81
82 void FGAIStorm::update(double dt) {
83    FGAIBase::update(dt);
84    Run(dt);
85    Transform();
86 }
87
88
89 void FGAIStorm::Run(double dt) {
90
91    FGAIStorm::dt = dt;
92         
93    double speed_north_deg_sec;
94    double speed_east_deg_sec;
95
96    // convert speed to degrees per second
97    speed_north_deg_sec = cos( hdg / SG_RADIANS_TO_DEGREES )
98                           * speed * 1.686 / ft_per_deg_lat;
99    speed_east_deg_sec  = sin( hdg / SG_RADIANS_TO_DEGREES )
100                           * speed * 1.686 / ft_per_deg_lon;
101
102    // set new position
103    pos.setlat( pos.lat() + speed_north_deg_sec * dt);
104    pos.setlon( pos.lon() + speed_east_deg_sec * dt); 
105
106    // do calculations for weather radar display 
107    UpdateRadar(manager);
108
109    // **************************************************
110    // *     do lightning                               *
111    // **************************************************
112
113    if (timer > random_delay) {
114      srand((unsigned)time(0));
115      random_delay = delay + (rand()%3) - 1.0;
116      //cout << "random_delay = " << random_delay << endl;
117      timer = 0.0;
118      flashing = true;
119      subflash_index++;
120      if (subflash_index == 8) subflash_index = 0; 
121      subflashes = subflash_array[subflash_index]; 
122    }
123
124    if (flashing) {
125      if (flashed < subflashes) {
126          timer += dt;
127          if (timer < 0.1) { 
128          flash_node->setBoolValue(true);
129          } else {
130             flash_node->setBoolValue(false);
131             if (timer > 0.2) {
132               timer = 0.0;
133               flashed++;
134             }
135          }
136      } else {
137        flashing = false;
138        timer = 0.0;
139        flashed = 0;
140      }
141    }
142    else {
143      timer += dt;
144    }  
145
146    // ***************************************************
147    // *      do turbulence                              *
148    // ***************************************************
149
150    // copy user's position from the AIManager
151    double user_latitude  = manager->get_user_latitude();
152    double user_longitude = manager->get_user_longitude();
153    double user_altitude  = manager->get_user_altitude();
154
155    // calculate range to target in feet and nautical miles
156    double lat_range = fabs(pos.lat() - user_latitude) * ft_per_deg_lat;
157    double lon_range = fabs(pos.lon() - user_longitude) * ft_per_deg_lon;
158    double range_ft = sqrt(lat_range*lat_range + lon_range*lon_range);
159    range = range_ft / 6076.11549;
160
161    if (range < (diameter * 0.5) &&
162        user_altitude > (altitude - 1000.0) &&
163        user_altitude < height) {
164               turb_mag_node->setDoubleValue(strength_norm);
165               turb_rate_node->setDoubleValue(0.5);
166    } 
167      
168 }
169