]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIStorm.cxx
#553: MP-model-loading related segfault
[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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 #include <Main/fg_props.hxx>
26 #include <Main/globals.hxx>
27 #include <Scenery/scenery.hxx>
28 #include <string>
29 #include <math.h>
30 #include <cstdlib>
31 #include <time.h>
32
33 using std::string;
34
35 #include "AIStorm.hxx"
36
37
38 FGAIStorm::FGAIStorm() :
39    FGAIBase(otStorm, false)
40 {
41    delay = 3.6;
42    subflashes = 1;
43    timer = 0.0;
44    random_delay = 3.6;
45    flash_node = fgGetNode("/environment/lightning/flash", true);
46    flash_node->setBoolValue(false);
47    flashed = 0; 
48    flashing = false;
49    subflash_index = -1;
50    subflash_array[0] =  1;
51    subflash_array[1] =  2;
52    subflash_array[2] =  1;
53    subflash_array[3] =  3;
54    subflash_array[4] =  2;
55    subflash_array[5] =  1;
56    subflash_array[6] =  1;
57    subflash_array[7] =  2;
58
59    turb_mag_node = fgGetNode("/environment/turbulence/magnitude-norm", true);
60    turb_rate_node = fgGetNode("/environment/turbulence/rate-hz", true);
61 }
62
63
64 FGAIStorm::~FGAIStorm() {
65 }
66
67 void FGAIStorm::readFromScenario(SGPropertyNode* scFileNode) {
68   if (!scFileNode)
69     return;
70
71   FGAIBase::readFromScenario(scFileNode);
72
73   setDiameter(scFileNode->getDoubleValue("diameter-ft", 0.0)/6076.11549);
74   setHeight(scFileNode->getDoubleValue("height-msl", 5000.0));
75   setStrengthNorm(scFileNode->getDoubleValue("strength-norm", 1.0)); 
76 }
77
78 bool FGAIStorm::init(bool search_in_AI_path) {
79    return FGAIBase::init(search_in_AI_path);
80 }
81
82 void FGAIStorm::bind() {
83     FGAIBase::bind();
84 }
85
86 void FGAIStorm::unbind() {
87     FGAIBase::unbind();
88 }
89
90
91 void FGAIStorm::update(double dt) {
92    FGAIBase::update(dt);
93    Run(dt);
94    Transform();
95 }
96
97
98 void FGAIStorm::Run(double dt) {
99
100    double speed_north_deg_sec;
101    double speed_east_deg_sec;
102
103    // convert speed to degrees per second
104    speed_north_deg_sec = cos( hdg / SG_RADIANS_TO_DEGREES )
105                           * speed * 1.686 / ft_per_deg_lat;
106    speed_east_deg_sec  = sin( hdg / SG_RADIANS_TO_DEGREES )
107                           * speed * 1.686 / ft_per_deg_lon;
108
109    // set new position
110    pos.setLatitudeDeg( pos.getLatitudeDeg() + speed_north_deg_sec * dt);
111    pos.setLongitudeDeg( pos.getLongitudeDeg() + speed_east_deg_sec * dt); 
112
113    // do calculations for weather radar display 
114    UpdateRadar(manager);
115
116    // **************************************************
117    // *     do lightning                               *
118    // **************************************************
119
120    if (timer > random_delay) {
121      srand((unsigned)time(0));
122      random_delay = delay + (rand()%3) - 1.0;
123      //cout << "random_delay = " << random_delay << endl;
124      timer = 0.0;
125      flashing = true;
126      subflash_index++;
127      if (subflash_index == 8) subflash_index = 0; 
128      subflashes = subflash_array[subflash_index]; 
129    }
130
131    if (flashing) {
132      if (flashed < subflashes) {
133          timer += dt;
134          if (timer < 0.1) { 
135          flash_node->setBoolValue(true);
136          } else {
137             flash_node->setBoolValue(false);
138             if (timer > 0.2) {
139               timer = 0.0;
140               flashed++;
141             }
142          }
143      } else {
144        flashing = false;
145        timer = 0.0;
146        flashed = 0;
147      }
148    }
149    else {
150      timer += dt;
151    }  
152
153    // ***************************************************
154    // *      do turbulence                              *
155    // ***************************************************
156
157    // copy user's position from the AIManager
158    double user_latitude  = manager->get_user_latitude();
159    double user_longitude = manager->get_user_longitude();
160    double user_altitude  = manager->get_user_altitude();
161
162    // calculate range to target in feet and nautical miles
163    double lat_range = fabs(pos.getLatitudeDeg() - user_latitude) * ft_per_deg_lat;
164    double lon_range = fabs(pos.getLongitudeDeg() - user_longitude) * ft_per_deg_lon;
165    double range_ft = sqrt(lat_range*lat_range + lon_range*lon_range);
166    range = range_ft / 6076.11549;
167
168    if (range < (diameter * 0.5) &&
169        user_altitude > (altitude_ft - 1000.0) &&
170        user_altitude < height) {
171               turb_mag_node->setDoubleValue(strength_norm);
172               turb_rate_node->setDoubleValue(0.5);
173    } 
174      
175 }
176