Merge branch 'master' of gitorious.org:fg/fgdata into Work
This commit is contained in:
commit
6b73af06f8
21 changed files with 6908 additions and 3076 deletions
3558
ATC/default.vce
3558
ATC/default.vce
File diff suppressed because it is too large
Load diff
BIN
ATC/default.wav
BIN
ATC/default.wav
Binary file not shown.
5732
Docs/getstart.pdf
5732
Docs/getstart.pdf
File diff suppressed because it is too large
Load diff
|
@ -120,6 +120,7 @@
|
|||
<property>/controls/flight/aileron</property>
|
||||
<dead-band type="double">0.01</dead-band>
|
||||
<offset type="double">0.0</offset>
|
||||
<squared type="bool">1</squared>
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
|
@ -138,6 +139,7 @@
|
|||
<dead-band type="double">0.01</dead-band>
|
||||
<offset type="double">0.0</offset>
|
||||
<factor type="double">-1.0</factor>
|
||||
<squared type="bool">1</squared>
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
|
@ -156,6 +158,7 @@
|
|||
<dead-band type="double">0.01</dead-band>
|
||||
<offset type="double">0.0</offset>
|
||||
<factor type="double">1.0</factor>
|
||||
<squared type="bool">1</squared>
|
||||
</binding>
|
||||
<!-- binding>
|
||||
<command>nasal</command>
|
||||
|
|
|
@ -211,6 +211,35 @@
|
|||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
<button n="18"> <!-- Labled as T5 -->
|
||||
<desc>Retract Spoilers</desc>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.stepSpoilers(-1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.stepSpoilers(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
<button n="19"> <!-- Labled as T6 -->
|
||||
<desc>Deploy Spoilers</desc>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.stepSpoilers(1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.stepSpoilers(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
<button n="20">
|
||||
<desc>thrust reverse</desc>
|
||||
<repeatable type="bool">false</repeatable>
|
||||
|
|
208
Input/Joysticks/SpeedLink/black-widow-force.xml
Normal file
208
Input/Joysticks/SpeedLink/black-widow-force.xml
Normal file
|
@ -0,0 +1,208 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Speedlink Black Widow Force
|
||||
|
||||
Copyright (C) 2010 Michael Landwehr (potholer(at)web.de).
|
||||
This file is released under the GPL license.
|
||||
|
||||
Overview over the Functions of Axes and Buttons:
|
||||
|
||||
Axes on the Stick:
|
||||
Axis 0 = Aileron
|
||||
Axis 1 = Elevator
|
||||
Axis 2 = Throttle
|
||||
Axis 3 = Rudder
|
||||
Axis 4 = View Direction
|
||||
Axis 5 = View Elevation
|
||||
|
||||
Buttons on the Stick:
|
||||
Button 0 = Center View (F1; backside)
|
||||
Button 1 = Brakes (F2)
|
||||
Button 2 = Elevator Trim up (F3)
|
||||
Button 3 = Elevator Trim down (F4)
|
||||
Button 4 = Flaps down (F5)
|
||||
Button 5 = Flaps up (F6)
|
||||
Button 6 = Gear down (F7)
|
||||
Button 7 = Gear up (F8)
|
||||
-->
|
||||
|
||||
<PropertyList>
|
||||
|
||||
<name>Black Widow Force</name>
|
||||
|
||||
<axis n="0">
|
||||
<desc>Aileron</desc>
|
||||
<binding>
|
||||
<command>property-scale</command>
|
||||
<property>/controls/flight/aileron</property>
|
||||
<power type="double">2</power>
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
<axis n="1">
|
||||
<desc>Elevator</desc>
|
||||
<binding>
|
||||
<command>property-scale</command>
|
||||
<property>/controls/flight/elevator</property>
|
||||
<factor type="double">-1.0</factor>
|
||||
<power type="double">2</power>
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
<axis n="2">
|
||||
<desc>Throttle</desc>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.throttleAxis()</script>
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
<axis n="3">
|
||||
<desc>Rudder</desc>
|
||||
<binding>
|
||||
<command>property-scale</command>
|
||||
<property>/controls/flight/rudder</property>
|
||||
<power type="double">2</power>
|
||||
</binding>
|
||||
</axis>
|
||||
|
||||
<axis n="4">
|
||||
<desc>View Direction</desc>
|
||||
<low>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property>/sim/current-view/goal-heading-offset-deg</property>
|
||||
<step type="double">2.0</step>
|
||||
</binding>
|
||||
</low>
|
||||
<high>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property>/sim/current-view/goal-heading-offset-deg</property>
|
||||
<step type="double">-2.0</step>
|
||||
</binding>
|
||||
</high>
|
||||
</axis>
|
||||
|
||||
<axis n="5">
|
||||
<desc>View Elevation</desc>
|
||||
<low>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property>/sim/current-view/goal-pitch-offset-deg</property>
|
||||
<step type="double">-2.0</step>
|
||||
</binding>
|
||||
</low>
|
||||
<high>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property>/sim/current-view/goal-pitch-offset-deg</property>
|
||||
<step type="double">2.0</step>
|
||||
</binding>
|
||||
</high>
|
||||
</axis>
|
||||
|
||||
<button n="0">
|
||||
<desc>Center View</desc>
|
||||
<repeatable type="bool">false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>view.resetView()</script>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<button n="1">
|
||||
<desc>Brakes</desc>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.applyBrakes(1, 0)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.applyBrakes(0, 0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
<button n="2">
|
||||
<desc>Elevator trim up</desc>
|
||||
<repeatable type="bool">true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.elevatorTrim(1)</script>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<button n="3">
|
||||
<desc>Elevator trim down</desc>
|
||||
<repeatable type="bool">true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.elevatorTrim(-1)</script>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<button n="4">
|
||||
<desc>Flaps down</desc>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.flapsDown(1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.flapsDown(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
<button n="5">
|
||||
<desc>Flaps up</desc>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.flapsDown(-1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.flapsDown(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
<button n="6">
|
||||
<desc>Gear down</desc>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.gearDown(1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.gearDown(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
<button n="7">
|
||||
<desc>Gear up</desc>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.gearDown(-1)</script>
|
||||
</binding>
|
||||
<mod-up>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>controls.gearDown(0)</script>
|
||||
</binding>
|
||||
</mod-up>
|
||||
</button>
|
||||
|
||||
</PropertyList>
|
||||
|
|
@ -35,3 +35,4 @@ WRITE ALLOW $FG_HOME/*.log
|
|||
WRITE ALLOW $FG_HOME/Export/*
|
||||
WRITE ALLOW $FG_HOME/state/*.xml
|
||||
WRITE ALLOW $FG_HOME/aircraft-data/*.xml
|
||||
WRITE ALLOW $FG_HOME/Wildfire/*.xml
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
var startEngine = func(v = 1) {
|
||||
if (!v)
|
||||
var startEngine = func(v = 1, which...) {
|
||||
if (!v and !size(which))
|
||||
return props.setAll("/controls/engines/engine", "starter", 0);
|
||||
foreach(var e; engines)
|
||||
if(e.selected.getValue())
|
||||
e.controls.getNode("starter").setBoolValue(v);
|
||||
if(size(which)) {
|
||||
foreach(var i; which)
|
||||
foreach(var e; engines)
|
||||
if(e.index == i)
|
||||
e.controls.getNode("starter").setBoolValue(v);
|
||||
} else {
|
||||
foreach(var e; engines)
|
||||
if(e.selected.getValue())
|
||||
e.controls.getNode("starter").setBoolValue(v);
|
||||
}
|
||||
}
|
||||
|
||||
var selectEngine = func(which) {
|
||||
|
|
|
@ -49,6 +49,23 @@ var menuEnable = func(searchname, state) {
|
|||
}
|
||||
}
|
||||
|
||||
##
|
||||
# Set the binding for a menu item to a Nasal script,
|
||||
# typically a dialog open() command.
|
||||
#
|
||||
var menuBind = func(searchname, command) {
|
||||
foreach (var menu; props.globals.getNode("/sim/menubar/default").getChildren("menu")) {
|
||||
foreach (item; menu.getChildren("item")) {
|
||||
foreach (name; item.getChildren("name")) {
|
||||
if (name.getValue() == searchname) {
|
||||
item.getNode("binding", 1).getNode("command", 1).setValue("nasal");
|
||||
item.getNode("binding", 1).getNode("script", 1).setValue(command);
|
||||
fgcommand("gui-redraw");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
##
|
||||
# Set mouse cursor coordinates and shape (number or name), and return
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
# add_vectors to add two vectors in polar coordinates
|
||||
# wind_altitude_interpolation to interpolate aloft winds in altitude
|
||||
# wind_interpolation to interpolate aloft winds in altitude and position
|
||||
# get_slowdown_fraction to compute the effect of boundary layer wind slowdown
|
||||
# interpolation_loop to continuously interpolate weather parameters between stations
|
||||
# thermal_lift_start to start the detailed thermal model
|
||||
# thermal_lift_loop to manage the detailed thermal lift model
|
||||
|
@ -340,6 +341,52 @@ return sum_wind;
|
|||
}
|
||||
|
||||
|
||||
###################################
|
||||
# boundary layer computations
|
||||
###################################
|
||||
|
||||
|
||||
var get_slowdown_fraction = func {
|
||||
|
||||
var tile_index = getprop(lw~"tiles/tile[4]/tile-index");
|
||||
var altitude_agl = getprop("/position/altitude-agl-ft");
|
||||
var altitude = getprop("/position/altitude-ft");
|
||||
|
||||
|
||||
|
||||
if (presampling_flag == 0)
|
||||
{
|
||||
var base_layer_thickness = 600.0;
|
||||
var f_slow = 1.0/3.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
var alt_median = alt_50_array[tile_index - 1];
|
||||
var alt_difference = alt_median - (altitude - altitude_agl);
|
||||
var base_layer_thickness = 150.0;
|
||||
|
||||
# get the boundary layer size dependent on terrain altitude above terrain median
|
||||
|
||||
if (alt_difference > 0.0) # we're low and the boundary layer grows
|
||||
{var boundary_alt = base_layer_thickness + 0.3 * alt_difference;}
|
||||
else # the boundary layer shrinks
|
||||
{var boundary_alt = base_layer_thickness + 0.1 * alt_difference;}
|
||||
|
||||
if (boundary_alt < 50.0){boundary_alt = 50.0;}
|
||||
if (boundary_alt > 3000.0) {boundary_alt = 3000.0;}
|
||||
|
||||
# get the boundary effect as a function of bounday layer size
|
||||
|
||||
var f_slow = 1.0 - (0.2 + 0.17 * math.ln(boundary_alt/base_layer_thickness));
|
||||
}
|
||||
|
||||
print("Boundary layer thickness: ",base_layer_thickness);
|
||||
print("Boundary layer slowdown: ", f_slow);
|
||||
|
||||
return f_slow;
|
||||
}
|
||||
|
||||
|
||||
###################################
|
||||
# interpolation management loop
|
||||
###################################
|
||||
|
@ -365,6 +412,7 @@ var n_stations = size(weatherStationArray);
|
|||
for (var i = 0; i < n_stations; i=i+1) {
|
||||
|
||||
s = weatherStationArray[i];
|
||||
|
||||
|
||||
var stpos = geo.Coord.new();
|
||||
stpos.set_latlon(s.lat,s.lon,0.0);
|
||||
|
@ -387,7 +435,8 @@ for (var i = 0; i < n_stations; i=i+1) {
|
|||
|
||||
# automatically delete stations out of range
|
||||
# take care not to unload if weird values appear for a moment
|
||||
if ((d > 80000.0) and (d<100000.0))
|
||||
# never unload if only one station left
|
||||
if ((d > 120000.0) and (d<140000.0) and (n_stations > 1))
|
||||
{
|
||||
if (debug_output_flag == 1)
|
||||
{print("Distance to weather station ", d, " m, unloading ...", i);}
|
||||
|
@ -3169,11 +3218,12 @@ if (dynamical_convection_flag == 1)
|
|||
}
|
||||
|
||||
|
||||
# if we can do so, we switch global weather off at this point
|
||||
# if we can do so, we switch global weather and METAR parsing in environment off at this point
|
||||
|
||||
if (compat_layer.features.can_disable_environment ==1)
|
||||
{
|
||||
props.globals.getNode("/environment/config/enabled").setBoolValue(0);
|
||||
props.globals.getNode("/environment/params/metar-updates-environment").setBoolValue(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3187,7 +3237,31 @@ if ((presampling_flag == 1) and (getprop(lw~"tmp/presampling-status") == "idle")
|
|||
}
|
||||
|
||||
|
||||
# see if we use METAR for weather setup
|
||||
|
||||
if ((getprop("/environment/metar/valid") == 1) and (getprop(lw~"tmp/tile-management") == "METAR"))
|
||||
{
|
||||
type = "METAR";
|
||||
metar_flag = 1;
|
||||
|
||||
setprop(lw~"METAR/station-id","METAR");
|
||||
|
||||
# switch off normal 3d clouds
|
||||
|
||||
var layers = props.globals.getNode("/environment/clouds").getChildren("layer");
|
||||
|
||||
foreach (l; layers)
|
||||
{
|
||||
l.getNode("coverage-type").setValue(5);
|
||||
}
|
||||
|
||||
}
|
||||
else if ((getprop("/environment/metar/valid") == 0) and (getprop(lw~"tmp/tile-management") == "METAR"))
|
||||
{
|
||||
print("No METAR available, aborting...");
|
||||
setprop("/sim/messages/pilot", "Local weather: No METAR available! Aborting...");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
# see if we need to create an aloft wind interpolation structure
|
||||
|
@ -3198,49 +3272,69 @@ if ((wind_model_flag == 3) or ((wind_model_flag ==5) and (getprop(lwi~"ipoint-nu
|
|||
|
||||
# prepare the first tile wind field
|
||||
|
||||
if (wind_model_flag == 5) # it needs to be interpolated
|
||||
if (metar_flag == 1) # the winds from current METAR are used
|
||||
{
|
||||
var res = wind_interpolation(lat,lon,0.0);
|
||||
if ((wind_model_flag == 1) or (wind_model_flag == 2))
|
||||
{
|
||||
# METAR reports ground winds, we want to set aloft, so we need to compute the local boundary layer
|
||||
# need to set the tile index for this
|
||||
setprop(lw~"tiles/tile[4]/tile-index",1);
|
||||
|
||||
append(weather_dynamics.tile_wind_direction,res[0]);
|
||||
append(weather_dynamics.tile_wind_speed,res[1]);
|
||||
var boundary_correction = 1.0/get_slowdown_fraction();
|
||||
|
||||
append(weather_dynamics.tile_wind_direction, getprop("environment/metar/base-wind-dir-deg"));
|
||||
append(weather_dynamics.tile_wind_speed, boundary_correction * getprop("environment/metar/base-wind-speed-kt"));
|
||||
setprop(lw~"tmp/tile-orientation-deg",getprop("environment/metar/base-wind-dir-deg"));
|
||||
}
|
||||
else
|
||||
{
|
||||
print("Wind model currently not supported with live data!");
|
||||
setprop("/sim/messages/pilot", "Local weather: Wind model currently not supported with live data! Aborting...");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (wind_model_flag == 3) # it comes from a different menu
|
||||
else
|
||||
{
|
||||
append(weather_dynamics.tile_wind_direction, getprop(lw~"tmp/FL0-wind-from-heading-deg"));
|
||||
append(weather_dynamics.tile_wind_speed, getprop(lw~"tmp/FL0-windspeed-kt"));
|
||||
}
|
||||
else # it comes from the standard menu
|
||||
{
|
||||
append(weather_dynamics.tile_wind_direction, getprop(lw~"tmp/tile-orientation-deg"));
|
||||
append(weather_dynamics.tile_wind_speed, getprop(lw~"tmp/windspeed-kt"));
|
||||
}
|
||||
|
||||
# when the aloft wind menu is used, the lowest winds should be taken from there
|
||||
# so we need to overwrite the setting from the tile generating menu in this case
|
||||
# otherwise the wrong orientation is built
|
||||
if (wind_model_flag == 5) # it needs to be interpolated
|
||||
{
|
||||
var res = wind_interpolation(lat,lon,0.0);
|
||||
|
||||
append(weather_dynamics.tile_wind_direction,res[0]);
|
||||
append(weather_dynamics.tile_wind_speed,res[1]);
|
||||
}
|
||||
else if (wind_model_flag == 3) # it comes from a different menu
|
||||
{
|
||||
append(weather_dynamics.tile_wind_direction, getprop(lw~"tmp/FL0-wind-from-heading-deg"));
|
||||
append(weather_dynamics.tile_wind_speed, getprop(lw~"tmp/FL0-windspeed-kt"));
|
||||
}
|
||||
else # it comes from the standard menu
|
||||
{
|
||||
append(weather_dynamics.tile_wind_direction, getprop(lw~"tmp/tile-orientation-deg"));
|
||||
append(weather_dynamics.tile_wind_speed, getprop(lw~"tmp/windspeed-kt"));
|
||||
}
|
||||
|
||||
# when the aloft wind menu is used, the lowest winds should be taken from there
|
||||
# so we need to overwrite the setting from the tile generating menu in this case
|
||||
# otherwise the wrong orientation is built
|
||||
|
||||
|
||||
if (wind_model_flag ==3)
|
||||
{
|
||||
setprop(lw~"tmp/tile-orientation-deg", getprop(lw~"tmp/FL0-wind-from-heading-deg"));
|
||||
}
|
||||
else if (wind_model_flag == 5)
|
||||
{
|
||||
setprop(lw~"tmp/tile-orientation-deg", weather_dynamics.tile_wind_direction[0]);
|
||||
}
|
||||
|
||||
if (wind_model_flag ==3)
|
||||
{
|
||||
setprop(lw~"tmp/tile-orientation-deg", getprop(lw~"tmp/FL0-wind-from-heading-deg"));
|
||||
}
|
||||
else if (wind_model_flag == 5)
|
||||
{
|
||||
setprop(lw~"tmp/tile-orientation-deg", weather_dynamics.tile_wind_direction[0]);
|
||||
}
|
||||
}
|
||||
|
||||
# create all the neighbouring tile coordinate sets
|
||||
|
||||
weather_tile_management.create_neighbours(lat,lon,getprop(lw~"tmp/tile-orientation-deg"));
|
||||
|
||||
|
||||
# see if we use METAR for weather setup
|
||||
|
||||
if ((getprop(lw~"METAR/available-flag") == 1) and (getprop(lw~"tmp/tile-management") == "METAR"))
|
||||
{type = "METAR";}
|
||||
|
||||
setprop(lw~"tiles/tile-counter",getprop(lw~"tiles/tile-counter")+1);
|
||||
|
||||
|
@ -3743,6 +3837,7 @@ var presampling_flag = 1;
|
|||
var detailed_clouds_flag = 1;
|
||||
var dynamical_convection_flag = 1;
|
||||
var debug_output_flag = 1;
|
||||
var metar_flag = 0;
|
||||
|
||||
|
||||
# set all sorts of default properties for the menu
|
||||
|
|
|
@ -252,7 +252,8 @@ var fly_by_view_handler = {
|
|||
me.latN = props.globals.getNode("/sim/viewer/latitude-deg", 1);
|
||||
me.lonN = props.globals.getNode("/sim/viewer/longitude-deg", 1);
|
||||
me.altN = props.globals.getNode("/sim/viewer/altitude-ft", 1);
|
||||
me.hdgN = props.globals.getNode("/orientation/heading-deg", 1);
|
||||
# me.hdgN = props.globals.getNode("/orientation/heading-deg", 1);
|
||||
me.hdgN = props.globals.getNode("/instrumentation/gps/indicated-track-true-deg", 1);
|
||||
|
||||
setlistener("/sim/signals/reinit", func(n) { n.getValue() or me.reset() });
|
||||
setlistener("/sim/crashed", func(n) { n.getValue() and me.reset() });
|
||||
|
|
|
@ -189,21 +189,60 @@ if (((local_weather.presampling_flag == 1) and (getprop(lw~"tmp/presampling-stat
|
|||
|
||||
if ((local_weather.wind_model_flag == 2) or (local_weather.wind_model_flag ==4))
|
||||
{
|
||||
alpha = alpha + 2.0 * (rand()-0.5) * 10.0;
|
||||
|
||||
if (local_weather.metar_flag == 0)
|
||||
{
|
||||
alpha = alpha + 2.0 * (rand()-0.5) * 10.0;
|
||||
# account for the systematic spin of weather systems around a low pressure
|
||||
# core dependent on hemisphere
|
||||
if (lat >0.0) {alpha = alpha -3.0;}
|
||||
else {alpha = alpha +3.0;}
|
||||
}
|
||||
else
|
||||
{
|
||||
var step = 20.0;
|
||||
|
||||
var alpha_test = getprop("/environment/metar/base-wind-dir-deg");
|
||||
|
||||
print("alpha: ", alpha, " alpha_test: ", alpha_test, " relangle: ", relangle(alpha, alpha_test));
|
||||
|
||||
if (relangle(alpha, alpha_test) > step)
|
||||
{
|
||||
print("Coordinate rotation by more than ",step," deg... compensating");
|
||||
if (relangle(alpha + step, alpha_test) < relangle(alpha-step, alpha_test))
|
||||
{
|
||||
alpha = alpha + step;
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha = alpha - step;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha = alpha_test;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# account for the systematic spin of weather systems around a low pressure
|
||||
# core dependent on hemisphere
|
||||
if (lat >0.0) {alpha = alpha -3.0;}
|
||||
else {alpha = alpha +3.0;}
|
||||
|
||||
|
||||
setprop(lw~"tmp/tile-orientation-deg",alpha);
|
||||
|
||||
# compute the new windspeed
|
||||
|
||||
var windspeed = getprop(lw~"tmp/windspeed-kt");
|
||||
windspeed = windspeed + 2.0 * (rand()-0.5) * 2.0;
|
||||
if (windspeed < 0) {windspeed = rand();}
|
||||
if (local_weather.metar_flag == 0)
|
||||
{
|
||||
var windspeed = getprop(lw~"tmp/windspeed-kt");
|
||||
windspeed = windspeed + 2.0 * (rand()-0.5) * 2.0;
|
||||
if (windspeed < 0) {windspeed = rand();}
|
||||
}
|
||||
else
|
||||
{
|
||||
var boundary_correction = 1.0/local_weather.get_slowdown_fraction();
|
||||
windspeed = boundary_correction * getprop("/environment/metar/base-wind-speed-kt");
|
||||
}
|
||||
|
||||
setprop(lw~"tmp/windspeed-kt",windspeed);
|
||||
|
||||
# store the tile orientation and wind strength in an array for fast processing
|
||||
|
@ -392,6 +431,10 @@ else if (getprop(lw~"tmp/tile-management") == "realistic weather")
|
|||
}
|
||||
|
||||
} # end if mode == realistic weather
|
||||
else if (getprop(lw~"tmp/tile-management") == "METAR")
|
||||
{
|
||||
weather_tiles.set_METAR_tile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1227,6 +1270,17 @@ return (x * math.cos(phi) + y * math.sin(phi)) * m_to_lon;
|
|||
}
|
||||
|
||||
|
||||
var relangle = func (alpha, beta) {
|
||||
|
||||
var angdiff = abs (alpha - beta);
|
||||
|
||||
if ((360.0 - angdiff) < angdiff)
|
||||
{angdiff = 360.0 - angdiff};
|
||||
|
||||
return angdiff;
|
||||
}
|
||||
|
||||
|
||||
var delete_from_vector = func(vec, index) {
|
||||
|
||||
var n = index+1;
|
||||
|
|
|
@ -1735,9 +1735,11 @@ var lon = 0.0;
|
|||
|
||||
|
||||
|
||||
var alpha = getprop(lw~"METAR/wind-direction-deg");
|
||||
var alpha = getprop("/environment/metar/base-wind-dir-deg");
|
||||
var phi = alpha * math.pi/180.0;
|
||||
var alt_offset = getprop(lw~"METAR/altitude-ft");
|
||||
var metar_alt_offset = 700.0 + getprop("/environment/metar/station-elevation-ft");
|
||||
|
||||
print("metar_alt_offset", metar_alt_offset);
|
||||
|
||||
# get the local time of the day in seconds
|
||||
|
||||
|
@ -1752,32 +1754,44 @@ calc_geo(blat);
|
|||
|
||||
# get the METAR position info
|
||||
|
||||
var station_lat = getprop(lw~"METAR/latitude-deg");
|
||||
var station_lon = getprop(lw~"METAR/longitude-deg");
|
||||
var station_lat = getprop("/environment/metar/station-latitude-deg");
|
||||
var station_lon = getprop("/environment/metar/station-longitude-deg");
|
||||
|
||||
|
||||
|
||||
# get the weather parameters
|
||||
|
||||
var vis = getprop(lw~"METAR/visibility-m");
|
||||
var T = getprop(lw~"METAR/temperature-degc");
|
||||
var D = getprop(lw~"METAR/dewpoint-degc");
|
||||
var p = getprop(lw~"METAR/pressure-inhg");
|
||||
var rain_norm = getprop(lw~"METAR/rain-norm");
|
||||
var snow_norm = getprop(lw~"METAR/snow-norm");
|
||||
var vis = getprop("/environment/metar/max-visibility-m");
|
||||
var T = getprop("/environment/metar/temperature-sea-level-degc");
|
||||
var D = getprop("/environment/metar/dewpoint-sea-level-degc");
|
||||
var p = getprop("/environment/metar/pressure-sea-level-inhg");
|
||||
var rain_norm = getprop("/environment/metar/rain-norm");
|
||||
var snow_norm = getprop("/environment/metar/snow-norm");
|
||||
|
||||
|
||||
if (getprop(lw~"METAR/station-id") != getprop("/environment/metar/station-id")) # the weather station has changed, set a new station
|
||||
{
|
||||
# set the cstation
|
||||
local_weather.set_weather_station(station_lat, station_lon, vis, T, D, p);
|
||||
|
||||
# and mark that we have used this station
|
||||
setprop(lw~"METAR/station-id",getprop("/environment/metar/station-id"));
|
||||
}
|
||||
|
||||
# and set the corresponding station
|
||||
local_weather.set_weather_station(station_lat, station_lon, vis, T, D, p);
|
||||
|
||||
# now get the cloud layer info
|
||||
|
||||
var layers = props.globals.getNode(lw~"METAR", 1).getChildren("layer");
|
||||
var layers = props.globals.getNode("/environment/metar/clouds", 1).getChildren("layer");
|
||||
var n_layers = size(layers); # the system initializes with 4 layers, but who knows...
|
||||
var n = 0; # start with lowest layer
|
||||
|
||||
# now determine the nature of the lowest layer
|
||||
|
||||
var cumulus_flag = 1; # default assumption - the lowest layer is cumulus
|
||||
var cover_low = layers[0].getNode("cover-oct").getValue();
|
||||
var alt_low = layers[0].getNode("alt-agl-ft").getValue();
|
||||
var cover_low = 8 - 2 * layers[0].getNode("coverage-type").getValue(); # conversion to oktas
|
||||
var alt_low = layers[0].getNode("elevation-ft").getValue();
|
||||
|
||||
print("alt_low: ", alt_low);
|
||||
|
||||
# first check a few obvious criteria
|
||||
|
||||
|
@ -1799,7 +1813,7 @@ if ((cover_low == 3) or (cover_low == 4)) # scattered
|
|||
|
||||
# now see if there is a layer shading convective development
|
||||
|
||||
var coverage_above = layers[1].getNode("cover-oct").getValue();
|
||||
var coverage_above = 8 - 2 * layers[1].getNode("coverage-type").getValue();
|
||||
if (coverage_above > 6) {cumulus_flag = 0;} # no Cumulus with strong layer above
|
||||
|
||||
# always do Cumulus when there's a thunderstorm
|
||||
|
@ -1812,66 +1826,90 @@ if (cumulus_flag == 1)
|
|||
{
|
||||
if ((cover_low < 4) and (t > 39600) and (t < 68400)) {var strength = 0.4;}
|
||||
else {var strength = 1.0;}
|
||||
local_weather.create_cumosys(blat,blon, alt_low+alt_offset,get_n(strength), 20000.0);
|
||||
local_weather.create_cumosys(blat,blon, alt_low+metar_alt_offset,get_n(strength), 20000.0);
|
||||
n = n + 1; # do not start parsing with lowest layer
|
||||
}
|
||||
|
||||
else
|
||||
{var strength = 0.0;}
|
||||
|
||||
for (var i = n; i <n_layers; i=i+1)
|
||||
{
|
||||
var altitude = layers[i].getNode("alt-agl-ft").getValue();
|
||||
var cover = layers[i].getNode("cover-oct").getValue();
|
||||
var altitude = layers[i].getNode("elevation-ft").getValue();
|
||||
print("altitude: ",altitude);
|
||||
var cover = 8 - 2 * layers[i].getNode("coverage-type").getValue();
|
||||
|
||||
if (cover == 0) {break;} # a zero cover layer indicates we are done
|
||||
if (cover == -2) {break;} # a clear cover layer indicates we are done
|
||||
|
||||
if (altitude < 9000.0) # draw Nimbostratus or Stratus models
|
||||
{
|
||||
if (cover == 8)
|
||||
{create_8_8_nimbus(blat, blon, altitude+alt_offset, alpha);}
|
||||
if ((altitude < 2000) or (rain_norm > 0.3))
|
||||
{create_8_8_nimbus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else
|
||||
{create_8_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else if ((cover < 8) and (cover > 4))
|
||||
{create_6_8_stratus(blat, blon, altitude+alt_offset, alpha);}
|
||||
{
|
||||
if (cumulus_flag == 1)
|
||||
{
|
||||
create_4_8_sstratus_patches(blat, blon, altitude+metar_alt_offset, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
create_6_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);
|
||||
}
|
||||
}
|
||||
else if ((cover == 3) or (cover == 4))
|
||||
{
|
||||
var rn = rand();
|
||||
if (rn > 0.75)
|
||||
{create_4_8_stratus(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_4_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else if (rn > 0.5)
|
||||
{create_4_8_stratus_patches(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_4_8_stratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else if (rn > 0.25)
|
||||
{create_4_8_sstratus_patches(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_4_8_sstratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else if (rn > 0.0)
|
||||
{create_4_8_sstratus_undulatus(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_4_8_sstratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
}
|
||||
else
|
||||
{
|
||||
var rn = rand();
|
||||
if (rn > 0.5)
|
||||
{create_2_8_stratus(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_2_8_stratus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else if (rn > 0.0)
|
||||
{create_2_8_sstratus(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_2_8_sstratus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
}
|
||||
} # end if altitude
|
||||
else if ((altitude > 9000.0) and (altitude < 20000.0)) # select thin cloud layers
|
||||
{
|
||||
if (cover == 8)
|
||||
{create_8_8_cirrostratus(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_8_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else if (cover > 2)
|
||||
{
|
||||
rn = rand();
|
||||
if (rn > 0.5)
|
||||
{create_4_8_tstratus_patches(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_4_8_tstratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else if (rn > 0.0)
|
||||
{create_4_8_tstratus_undulatus(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_4_8_tstratus_undulatus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
}
|
||||
else
|
||||
{create_2_8_tstratus(blat, blon, altitude+alt_offset, alpha);}
|
||||
{create_2_8_tstratus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
} # end if altitude
|
||||
else
|
||||
{
|
||||
if (cover == 8)
|
||||
{create_8_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else if (cover > 4)
|
||||
{create_6_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else if (cover > 2)
|
||||
{create_4_8_cirrostratus_patches(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
else
|
||||
{create_2_8_cirrostratus(blat, blon, altitude+metar_alt_offset, alpha);}
|
||||
|
||||
|
||||
}
|
||||
} # end for
|
||||
|
||||
# now that the weather info is used, set the flag so that offline mode starts unless a new METAR
|
||||
# is available for the next tile
|
||||
|
||||
setprop(lw~"METAR/available-flag",0);
|
||||
|
||||
# store convective altitude and strength
|
||||
|
||||
|
@ -1908,6 +1946,12 @@ local_weather.create_streak("Stratus",lat, lon, alt,500.0,20,0.0,0.2,20000.0,20,
|
|||
}
|
||||
|
||||
|
||||
var create_6_8_cirrostratus = func (lat, lon, alt, alpha) {
|
||||
|
||||
local_weather.create_streak("Cirrostratus",lat,lon,alt,500.0,24,1500.0,0.0,900.0,24,1500.0,0.0,900.0,alpha,1.0);
|
||||
}
|
||||
|
||||
|
||||
var create_4_8_stratus = func (lat, lon, alt, alpha) {
|
||||
|
||||
var phi = alpha * math.pi/180.0;
|
||||
|
@ -2193,6 +2237,27 @@ for (var i=0; i<25; i=i+1)
|
|||
}
|
||||
|
||||
|
||||
var create_1_8_cirrocumulus = func (lat, lon, alt, alpha) {
|
||||
|
||||
var phi = alpha * math.pi/180.0;
|
||||
|
||||
for (var i = 0; i < 2; i = i + 1)
|
||||
{
|
||||
var x = 2.0 * (rand()-0.5) * 10000;
|
||||
var y = -6000 + i * 12000 + 2.0 * (rand()-0.5) * 1000;
|
||||
|
||||
var beta = rand() * 90;
|
||||
var alt_variation = rand() * 2000;
|
||||
|
||||
var path = local_weather.select_cloud_model("Cirrocumulus", "large");
|
||||
compat_layer.create_cloud(path, lat + get_lat(x,y,phi), lon+get_lon(x,y,phi), alt + alt_variation,alpha+ beta);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
var create_stratocumulus_bank = func (lat, lon, alt, alpha) {
|
||||
|
||||
var phi = alpha * math.pi/180.0;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// This shader is mostly an adaptation of the shader found at
|
||||
// http://www.bonzaisoftware.com/water_tut.html and its glsl conversion
|
||||
// available at http://forum.bonzaisoftware.com/viewthread.php?tid=10
|
||||
// © Michael Horsch - 2005
|
||||
|
||||
uniform sampler2D water_normalmap;
|
||||
uniform sampler2D water_reflection;
|
||||
uniform sampler2D water_dudvmap;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// This shader is mostly an adaptation of the shader found at
|
||||
// http://www.bonzaisoftware.com/water_tut.html and its glsl conversion
|
||||
// available at http://forum.bonzaisoftware.com/viewthread.php?tid=10
|
||||
// © Michael Horsch - 2005
|
||||
|
||||
varying vec4 waterTex1;
|
||||
varying vec4 waterTex2;
|
||||
varying vec4 waterTex4;
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<property>/sim/version/flightgear</property>
|
||||
</text>
|
||||
<text>
|
||||
<label>(c) 1996-2010, the FlightGear contributors</label>
|
||||
<label>(c) 1996-2011, the FlightGear contributors</label>
|
||||
</text>
|
||||
<text>
|
||||
<label>http://www.flightgear.org/</label>
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
<col>3</col>
|
||||
<width>75</width>
|
||||
<height>25</height>
|
||||
<live>true</live>
|
||||
<property>/instrumentation/altimeter/setting-inhg</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
|
@ -185,6 +186,7 @@
|
|||
<col>3</col>
|
||||
<width>75</width>
|
||||
<height>25</height>
|
||||
<live>true</live>
|
||||
<property>/instrumentation/heading-indicator/offset-deg</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
|
||||
<input>
|
||||
<row>0</row><col>2</col>
|
||||
<live>true</live>
|
||||
<property>/sim/gui/dialogs/location-on-ground/airport</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
|
|
|
@ -235,23 +235,49 @@
|
|||
</binding>
|
||||
</checkbox>
|
||||
|
||||
<!--
|
||||
|
||||
<group>
|
||||
<layout>hbox</layout>
|
||||
<halign>right</halign>
|
||||
<text>
|
||||
<label>Cloud density</label>
|
||||
<enable>
|
||||
<and>
|
||||
<property>/sim/rendering/shader-effects</property>
|
||||
<property>/sim/rendering/clouds3d-enable</property>
|
||||
</and>
|
||||
</enable>
|
||||
</text>
|
||||
<slider>
|
||||
<name>cloud-density</name>
|
||||
<enable>
|
||||
<and>
|
||||
<property>/sim/rendering/shader-effects</property>
|
||||
<property>/sim/rendering/clouds3d-enable</property>
|
||||
</and>
|
||||
</enable>
|
||||
<min>0</min>
|
||||
<max>1.0</max>
|
||||
<property>/sim/rendering/clouds3d-density</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
<object-name>cloud-density</object-name>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>property-toggle</command>
|
||||
<property>/sim/rendering/clouds3d-enable</property>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>property-toggle</command>
|
||||
<property>/sim/rendering/clouds3d-enable</property>
|
||||
</binding>
|
||||
</slider>
|
||||
<text>
|
||||
<enable>
|
||||
<and>
|
||||
<property>/sim/rendering/shader-effects</property>
|
||||
<property>/sim/rendering/clouds3d-enable</property>
|
||||
</and>
|
||||
</enable>
|
||||
<label>12345678</label>
|
||||
<format>%.2f</format>
|
||||
<live>true</live>
|
||||
|
@ -259,8 +285,6 @@
|
|||
</text>
|
||||
</group>
|
||||
|
||||
-->
|
||||
|
||||
<group>
|
||||
<layout>hbox</layout>
|
||||
<halign>right</halign>
|
||||
|
|
|
@ -273,6 +273,7 @@
|
|||
|
||||
<item>
|
||||
<label>Autopilot Settings (F11)</label>
|
||||
<name>autopilot-settings</name>
|
||||
<binding>
|
||||
<command>dialog-show</command>
|
||||
<dialog-name>autopilot</dialog-name>
|
||||
|
@ -378,6 +379,7 @@
|
|||
|
||||
<item>
|
||||
<label>Map</label>
|
||||
<name>map</name>
|
||||
<binding>
|
||||
<command>dialog-show</command>
|
||||
<dialog-name>map</dialog-name>
|
||||
|
@ -403,6 +405,7 @@
|
|||
|
||||
<item>
|
||||
<label>Radio Settings (F12)</label>
|
||||
<name>radio</name>
|
||||
<binding>
|
||||
<command>dialog-show</command>
|
||||
<dialog-name>radios</dialog-name>
|
||||
|
@ -411,6 +414,7 @@
|
|||
|
||||
<item>
|
||||
<label>GPS Settings</label>
|
||||
<name>gps</name>
|
||||
<binding>
|
||||
<command>dialog-show</command>
|
||||
<dialog-name>gps</dialog-name>
|
||||
|
|
|
@ -328,7 +328,10 @@ top down before the key bindings are parsed.
|
|||
<name>'</name>
|
||||
<desc>Display a dialog relevant to the tuned in ATC service (if any)</desc>
|
||||
<binding>
|
||||
<!-- At the moment, we have no working interactive ATC, so this is
|
||||
disabled for v2.2.0.
|
||||
<command>ATC-dialog</command>
|
||||
-->
|
||||
</binding>
|
||||
</key>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue