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