]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIStorm.cxx
a4f2c4543c9660f385bb2cbd1a8209dba0a49161
[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 #include <time.h>
33
34 SG_USING_STD(string);
35
36 #include "AIStorm.hxx"
37
38
39 FGAIStorm::FGAIStorm(FGAIManager* mgr) {
40    manager = mgr;   
41    _type_str = "thunderstorm";
42    _otype = otStorm;
43    delay = 3.6;
44    subflashes = 1;
45    timer = 0.0;
46    random_delay = 3.6;
47    flash_node = fgGetNode("/environment/lightning/flash", true);
48    flash_node->setBoolValue(false);
49    flashed = 0; 
50    flashing = false;
51    subflash_index = -1;
52    subflash_array[0] =  1;
53    subflash_array[1] =  2;
54    subflash_array[2] =  1;
55    subflash_array[3] =  3;
56    subflash_array[4] =  2;
57    subflash_array[5] =  1;
58    subflash_array[6] =  1;
59    subflash_array[7] =  2;
60
61    turb_mag_node = fgGetNode("/environment/turbulence/magnitude-norm", true);
62    turb_rate_node = fgGetNode("/environment/turbulence/rate-hz", true);
63 }
64
65
66 FGAIStorm::~FGAIStorm() {
67 }
68
69
70 bool FGAIStorm::init() {
71    return FGAIBase::init();
72 }
73
74 void FGAIStorm::bind() {
75     FGAIBase::bind();
76 }
77
78 void FGAIStorm::unbind() {
79     FGAIBase::unbind();
80 }
81
82
83 void FGAIStorm::update(double dt) {
84    FGAIBase::update(dt);
85    Run(dt);
86    Transform();
87 }
88
89
90 void FGAIStorm::Run(double dt) {
91
92    FGAIStorm::dt = dt;
93         
94    double speed_north_deg_sec;
95    double speed_east_deg_sec;
96
97    // convert speed to degrees per second
98    speed_north_deg_sec = cos( hdg / SG_RADIANS_TO_DEGREES )
99                           * speed * 1.686 / ft_per_deg_lat;
100    speed_east_deg_sec  = sin( hdg / SG_RADIANS_TO_DEGREES )
101                           * speed * 1.686 / ft_per_deg_lon;
102
103    // set new position
104    pos.setlat( pos.lat() + speed_north_deg_sec * dt);
105    pos.setlon( pos.lon() + speed_east_deg_sec * dt); 
106
107    // do calculations for weather radar display 
108    UpdateRadar(manager);
109
110    // **************************************************
111    // *     do lightning                               *
112    // **************************************************
113
114    if (timer > random_delay) {
115      srand((unsigned)time(0));
116      random_delay = delay + (rand()%3) - 1.0;
117      //cout << "random_delay = " << random_delay << endl;
118      timer = 0.0;
119      flashing = true;
120      subflash_index++;
121      if (subflash_index == 8) subflash_index = 0; 
122      subflashes = subflash_array[subflash_index]; 
123    }
124
125    if (flashing) {
126      if (flashed < subflashes) {
127          timer += dt;
128          if (timer < 0.1) { 
129          flash_node->setBoolValue(true);
130          } else {
131             flash_node->setBoolValue(false);
132             if (timer > 0.2) {
133               timer = 0.0;
134               flashed++;
135             }
136          }
137      } else {
138        flashing = false;
139        timer = 0.0;
140        flashed = 0;
141      }
142    }
143    else {
144      timer += dt;
145    }  
146
147    // ***************************************************
148    // *      do turbulence                              *
149    // ***************************************************
150
151    // copy user's position from the AIManager
152    double user_latitude  = manager->get_user_latitude();
153    double user_longitude = manager->get_user_longitude();
154    double user_altitude  = manager->get_user_altitude();
155
156    // calculate range to target in feet and nautical miles
157    double lat_range = fabs(pos.lat() - user_latitude) * ft_per_deg_lat;
158    double lon_range = fabs(pos.lon() - user_longitude) * ft_per_deg_lon;
159    double range_ft = sqrt(lat_range*lat_range + lon_range*lon_range);
160    range = range_ft / 6076.11549;
161
162    if (range < (diameter * 0.5) &&
163        user_altitude > (altitude - 1000.0) &&
164        user_altitude < height) {
165               turb_mag_node->setDoubleValue(strength_norm);
166               turb_rate_node->setDoubleValue(0.5);
167    } 
168      
169 }
170