Merge branch 'master' of gitorious.org:fg/fgdata
This commit is contained in:
commit
091fbf80f0
68 changed files with 4498 additions and 736 deletions
|
@ -7,21 +7,21 @@
|
|||
<label>Cessna C172P</label>
|
||||
<enabled type="bool">true</enabled>
|
||||
<item>
|
||||
<label>Select Livery</label>
|
||||
<name>select-livery</name>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>aircraft.livery.dialog.toggle()</script>
|
||||
</binding>
|
||||
</item>
|
||||
<item>
|
||||
<label>Immatriculation</label>
|
||||
<name>immatriculation</name>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>c172p.immat_dialog.toggle()</script>
|
||||
</binding>
|
||||
</item>
|
||||
<item>
|
||||
<label>Show/hide yoke</label>
|
||||
<name>show-hide-yokes</name>
|
||||
<binding>
|
||||
<command>property-toggle</command>
|
||||
<property>sim/model/hide-yoke</property>
|
||||
|
|
|
@ -108,6 +108,10 @@
|
|||
<name>Alt + mouse click</name>
|
||||
<desc>move selected object(s) to new place</desc>
|
||||
</key>
|
||||
<key>
|
||||
<name>Ctrl + Alt + mouse click</name>
|
||||
<desc>Print lat/lon/alt and landclass of mouse click position</desc>
|
||||
</key>
|
||||
<key>
|
||||
<name>g (gear) + click</name>
|
||||
<desc>teleport to click position, looking at active object</desc>
|
||||
|
|
|
@ -435,6 +435,17 @@ var modelmgr = {
|
|||
me.mouse_coord = mouse_coord;
|
||||
status_dialog.open();
|
||||
adjust_dialog.center_sliders();
|
||||
|
||||
if (KbdAlt.getValue() and KbdCtrl.getValue()) { # Provide information on the selected point
|
||||
var geod = geodinfo(me.mouse_coord.lat(), me.mouse_coord.lon());
|
||||
var landclass = string.join(" ", geod[1].names);
|
||||
var str = sprintf("lat:%.4f lon:%.4f alt:%.0fm class(es): %s",
|
||||
me.mouse_coord.lat(), me.mouse_coord.lon(),
|
||||
me.mouse_coord.alt(), landclass);
|
||||
gui.popupTip(str, 3);
|
||||
print(str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (KbdAlt.getValue()) { # move active object here (and other selected ones along with it)
|
||||
(me.active == nil) and return;
|
||||
|
|
|
@ -143,6 +143,8 @@ alpha-test - children: active, comparison, reference
|
|||
Valid values for comparision:
|
||||
never, less, equal, lequal, greater, notequal, gequal,
|
||||
always
|
||||
|
||||
alpha-to-coverage - true, false
|
||||
|
||||
blend - children: active, source, destination, source-rgb,
|
||||
source-alpha, destination-rgb, destination-alpha
|
||||
|
|
|
@ -120,9 +120,25 @@ tree-height-m : The average height of the trees. Actual tree height will
|
|||
|
||||
tree-width-m : The average width of the tree cover. Actual tree width will
|
||||
vary by +/- 50%. (default 0)
|
||||
|
||||
tree-max-density-angle-deg : The slope angle at which trees begin to thin out
|
||||
as the slope is too steep to support the full coverage. Shallower
|
||||
slopes have maximum wood-coverage. Steeper slopes have fewer trees.
|
||||
(default : 45)
|
||||
|
||||
tree-zero-density-angle-deg : The angle at which the slope is too steep to
|
||||
support significant vegetation. Steeper slopes have no trees.
|
||||
(default : 60)
|
||||
|
||||
object-max-density-angle-deg : The angle at which objects and buildings become
|
||||
less dense due to a steep slope. (default : 20)
|
||||
|
||||
object-zero-density-angle-deg : The angle at which the slope is too steep to build
|
||||
on. No object/buildings will be placed on slopes steeper than this.
|
||||
(default : 30)
|
||||
|
||||
object-group : A group of random objects to be placed on the surface. Contains
|
||||
<range-m> and one or mode <object> children.
|
||||
<range-m> and one or more <object> children.
|
||||
|
||||
range-m : The distance at which objects within this object-group become
|
||||
visible. Note that for realism, 60% of the objects will become visible
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
<eye_alt><use>/sim/rendering/eye-altitude-m</use></eye_alt>
|
||||
<snow_level><use>/environment/snow-level-m</use></snow_level>
|
||||
<dust_cover_factor><use>/environment/surface/dust-cover-factor</use></dust_cover_factor>
|
||||
<lichen_cover_factor><use>/environment/surface/lichen-cover-factor</use></lichen_cover_factor>
|
||||
<wetness><use>/environment/surface/wetness</use></wetness>
|
||||
<fogtype><use>/sim/rendering/shaders/skydome</use></fogtype>
|
||||
<fogstructure><use>/environment/fog-structure</use></fogstructure>
|
||||
|
@ -261,6 +262,11 @@
|
|||
<type>float</type>
|
||||
<value><use>dust_cover_factor</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>lichen_cover_factor</name>
|
||||
<type>float</type>
|
||||
<value> <use>lichen_cover_factor</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>wetness</name>
|
||||
<type>float</type>
|
||||
|
|
226
Effects/tree.eff
226
Effects/tree.eff
|
@ -25,20 +25,131 @@
|
|||
<terminator><use>/environment/terminator-relative-position-m</use></terminator>
|
||||
<fogtype><use>/sim/rendering/shaders/skydome</use></fogtype>
|
||||
<terrain_alt><use>/environment/mean-terrain-elevation-m</use></terrain_alt>
|
||||
<overcast><use>/rendering/scene/overcast</use></overcast>
|
||||
<eye_alt><use>/sim/rendering/eye-altitude-m</use></eye_alt>
|
||||
<overcast><use>/rendering/scene/overcast</use></overcast>
|
||||
<eye_alt><use>/sim/rendering/eye-altitude-m</use></eye_alt>
|
||||
<snow_level><use>/environment/snow-level-m</use></snow_level>
|
||||
<dust_cover_factor><use>/environment/surface/dust-cover-factor</use></dust_cover_factor>
|
||||
<fogtype><use>/sim/rendering/shaders/skydome</use></fogtype>
|
||||
<fogstructure><use>/environment/fog-structure</use></fogstructure>
|
||||
<quality_level><use>/sim/rendering/shaders/landmass</use></quality_level>
|
||||
<!-- END fog include -->
|
||||
</parameters>
|
||||
|
||||
<technique n="4">
|
||||
<predicate>
|
||||
<and>
|
||||
<property>/sim/rendering/shaders/skydome</property>
|
||||
<property>/sim/rendering/random-vegetation</property>
|
||||
<or>
|
||||
<less-equal>
|
||||
<value type="float">2.0</value>
|
||||
<glversion/>
|
||||
</less-equal>
|
||||
<and>
|
||||
<extension-supported>GL_ARB_shader_objects</extension-supported>
|
||||
<extension-supported>GL_ARB_shading_language_100</extension-supported>
|
||||
<extension-supported>GL_ARB_vertex_shader</extension-supported>
|
||||
<extension-supported>GL_ARB_fragment_shader</extension-supported>
|
||||
<extension-supported>GL_ARB_multisample</extension-supported>
|
||||
</and>
|
||||
</or>
|
||||
</and>
|
||||
</predicate>
|
||||
|
||||
<pass>
|
||||
<lighting>true</lighting>
|
||||
<material>
|
||||
<ambient type="vec4d">1.0 1.0 1.0 1.0</ambient>
|
||||
<diffuse type="vec4d">1.0 1.0 1.0 1.0</diffuse>
|
||||
<color-mode>off</color-mode>
|
||||
</material>
|
||||
<texture-unit>
|
||||
<unit>0</unit>
|
||||
<type>2d</type>
|
||||
<image>
|
||||
<use>texture[0]/image</use>
|
||||
</image>
|
||||
<wrap-s>clamp</wrap-s>
|
||||
<wrap-t>clamp</wrap-t>
|
||||
</texture-unit>
|
||||
<alpha-to-coverage>true</alpha-to-coverage>
|
||||
<program>
|
||||
<vertex-shader>Shaders/tree-haze.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/tree-haze.frag</fragment-shader>
|
||||
</program>
|
||||
<uniform>
|
||||
<name>visibility</name>
|
||||
<type>float</type>
|
||||
<value><use>visibility</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>avisibility</name>
|
||||
<type>float</type>
|
||||
<value><use>avisibility</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>hazeLayerAltitude</name>
|
||||
<type>float</type>
|
||||
<value><use>lthickness</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>scattering</name>
|
||||
<type>float</type>
|
||||
<value><use>scattering</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>ground_scattering</name>
|
||||
<type>float</type>
|
||||
<value><use>ground_scattering</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>terminator</name>
|
||||
<type>float</type>
|
||||
<value><use>terminator</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>terrain_alt</name>
|
||||
<type>float</type>
|
||||
<value><use>terrain_alt</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>overcast</name>
|
||||
<type>float</type>
|
||||
<value><use>overcast</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>eye_alt</name>
|
||||
<type>float</type>
|
||||
<value><use>eye_alt</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>dust_cover_factor</name>
|
||||
<type>float</type>
|
||||
<value> <use>dust_cover_factor</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>texture</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">0</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>colorMode</name>
|
||||
<type>int</type>
|
||||
<value>2</value> <!-- AMBIENT_AND_DIFFUSE -->
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>quality_level</name>
|
||||
<type>int</type>
|
||||
<value> <use>quality_level</use></value>
|
||||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
|
||||
<technique n="5">
|
||||
<predicate>
|
||||
<and>
|
||||
<property>/sim/rendering/shaders/skydome</property>
|
||||
<property>/sim/rendering/random-vegetation</property>
|
||||
<property>/sim/rendering/random-vegetation</property>
|
||||
<or>
|
||||
<less-equal>
|
||||
<value type="float">2.0</value>
|
||||
|
@ -123,6 +234,11 @@
|
|||
<type>float</type>
|
||||
<value><use>eye_alt</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>dust_cover_factor</name>
|
||||
<type>float</type>
|
||||
<value> <use>dust_cover_factor</use></value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>texture</name>
|
||||
<type>sampler-2d</type>
|
||||
|
@ -133,16 +249,15 @@
|
|||
<type>int</type>
|
||||
<value>2</value> <!-- AMBIENT_AND_DIFFUSE -->
|
||||
</uniform>
|
||||
<!--<depth>
|
||||
<function>lequal</function>
|
||||
<write-mask type="bool">false</write-mask>
|
||||
</depth>-->
|
||||
<uniform>
|
||||
<name>quality_level</name>
|
||||
<type>int</type>
|
||||
<value> <use>quality_level</use></value>
|
||||
</uniform>
|
||||
</pass>
|
||||
|
||||
|
||||
</technique>
|
||||
|
||||
<technique n="9">
|
||||
|
||||
<technique n="8">
|
||||
<predicate>
|
||||
<and>
|
||||
<property>/sim/rendering/rembrandt/enabled</property>
|
||||
|
@ -182,6 +297,95 @@
|
|||
</uniform>
|
||||
</pass>
|
||||
</technique>
|
||||
|
||||
<technique n="9">
|
||||
<predicate>
|
||||
<and>
|
||||
<property>/sim/rendering/random-vegetation</property>
|
||||
<extension-supported>GL_ARB_multisample</extension-supported>
|
||||
<extension-supported>GL_ARB_vertex_shader</extension-supported>
|
||||
<extension-supported>GL_ARB_fragment_shader</extension-supported>
|
||||
<less-equal>
|
||||
<value type="float">1.0</value>
|
||||
<shader-language/>
|
||||
</less-equal>
|
||||
</and>
|
||||
</predicate>
|
||||
<pass n="0">
|
||||
<lighting>true</lighting>
|
||||
<material>
|
||||
<ambient type="vec4d">1.0 1.0 1.0 1.0</ambient>
|
||||
<diffuse type="vec4d">1.0 1.0 1.0 1.0</diffuse>
|
||||
<color-mode>off</color-mode>
|
||||
</material>
|
||||
<alpha-to-coverage>true</alpha-to-coverage>
|
||||
<texture-unit>
|
||||
<unit>0</unit>
|
||||
<type>2d</type>
|
||||
<image>
|
||||
<use>texture[0]/image</use>
|
||||
</image>
|
||||
<wrap-s>clamp</wrap-s>
|
||||
<wrap-t>clamp</wrap-t>
|
||||
</texture-unit>
|
||||
<program>
|
||||
<!-- <vertex-shader>Shaders/include_fog.vert</vertex-shader> -->
|
||||
<vertex-shader>Shaders/tree.vert</vertex-shader>
|
||||
<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
|
||||
<fragment-shader n="1">Shaders/tree.frag</fragment-shader>
|
||||
</program>
|
||||
<uniform>
|
||||
<name>baseTexture</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">0</value>
|
||||
</uniform>
|
||||
<!-- BEGIN fog include -->
|
||||
<uniform>
|
||||
<name>visibility</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>visibility</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>avisibility</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>avisibility</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>hazeLayerAltitude</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>lthickness</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>scattering</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>scattering</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>terminator</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>terminator</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>fogType</name>
|
||||
<type>int</type>
|
||||
<value>
|
||||
<use>fogtype</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<!-- END fog include -->
|
||||
</pass>
|
||||
</technique>
|
||||
|
||||
<technique n="10">
|
||||
<predicate>
|
||||
<and>
|
||||
|
|
|
@ -146,6 +146,363 @@
|
|||
</generate>
|
||||
|
||||
|
||||
<technique n="2">
|
||||
<predicate>
|
||||
<and>
|
||||
<property>/sim/rendering/shaders/skydome</property>
|
||||
<less-equal>
|
||||
<value type="float">5.0</value>
|
||||
<float-property>/sim/rendering/shaders/water</float-property>
|
||||
</less-equal>
|
||||
<or>
|
||||
<less-equal>
|
||||
<value type="float">2.0</value>
|
||||
<glversion/>
|
||||
</less-equal>
|
||||
<and>
|
||||
<extension-supported>GL_ARB_shader_objects</extension-supported>
|
||||
<extension-supported>GL_ARB_shading_language_100</extension-supported>
|
||||
<extension-supported>GL_ARB_vertex_shader</extension-supported>
|
||||
<extension-supported>GL_ARB_fragment_shader</extension-supported>
|
||||
</and>
|
||||
</or>
|
||||
</and>
|
||||
</predicate>
|
||||
|
||||
<pass>
|
||||
<lighting>true</lighting>
|
||||
<material>
|
||||
<ambient>
|
||||
<use>material/ambient</use>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<use>material/diffuse</use>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<use>material/specular</use>
|
||||
</specular>
|
||||
<color-mode>ambient-and-diffuse</color-mode>
|
||||
</material>
|
||||
<blend>
|
||||
<use>transparent</use>
|
||||
</blend>
|
||||
<alpha-test>
|
||||
<use>transparent</use>
|
||||
</alpha-test>
|
||||
<shade-model>smooth</shade-model>
|
||||
<cull-face>back</cull-face>
|
||||
<render-bin>
|
||||
<bin-number>
|
||||
<use>render-bin/bin-number</use>
|
||||
</bin-number>
|
||||
<bin-name>
|
||||
<use>render-bin/bin-name</use>
|
||||
</bin-name>
|
||||
</render-bin>
|
||||
<!--<texture-unit>
|
||||
<unit>0</unit>
|
||||
<image>
|
||||
<use>texture[0]/image</use>
|
||||
</image>
|
||||
<filter>
|
||||
<use>texture[0]/filter</use>
|
||||
</filter>
|
||||
<wrap-s>
|
||||
<use>texture[0]/wrap-s</use>
|
||||
</wrap-s>
|
||||
<wrap-t>
|
||||
<use>texture[0]/wrap-t</use>
|
||||
</wrap-t>
|
||||
<internal-format>
|
||||
<use>texture[0]/internal-format</use>
|
||||
</internal-format>
|
||||
</texture-unit>-->
|
||||
<texture-unit>
|
||||
<unit>2</unit>
|
||||
<image>
|
||||
<use>texture[2]/image</use>
|
||||
</image>
|
||||
<filter>
|
||||
<use>texture[2]/filter</use>
|
||||
</filter>
|
||||
<wrap-s>
|
||||
<use>texture[2]/wrap-s</use>
|
||||
</wrap-s>
|
||||
<wrap-t>
|
||||
<use>texture[2]/wrap-t</use>
|
||||
</wrap-t>
|
||||
<internal-format>
|
||||
<use>texture[2]/internal-format</use>
|
||||
</internal-format>
|
||||
</texture-unit>
|
||||
<texture-unit>
|
||||
<unit>3</unit>
|
||||
<image>
|
||||
<use>texture[3]/image</use>
|
||||
</image>
|
||||
<filter>
|
||||
<use>texture[3]/filter</use>
|
||||
</filter>
|
||||
<wrap-s>
|
||||
<use>texture[3]/wrap-s</use>
|
||||
</wrap-s>
|
||||
<wrap-t>
|
||||
<use>texture[3]/wrap-t</use>
|
||||
</wrap-t>
|
||||
<internal-format>
|
||||
<use>texture[3]/internal-format</use>
|
||||
</internal-format>
|
||||
</texture-unit>
|
||||
<!--<texture-unit>
|
||||
<unit>4</unit>
|
||||
<image>
|
||||
<use>texture[4]/image</use>
|
||||
</image>
|
||||
<filter>
|
||||
<use>texture[4]/filter</use>
|
||||
</filter>
|
||||
<wrap-s>
|
||||
<use>texture[4]/wrap-s</use>
|
||||
</wrap-s>
|
||||
<wrap-t>
|
||||
<use>texture[4]/wrap-t</use>
|
||||
</wrap-t>
|
||||
<internal-format>
|
||||
<use>texture[4]/internal-format</use>
|
||||
</internal-format>
|
||||
</texture-unit>-->
|
||||
<texture-unit>
|
||||
<unit>5</unit>
|
||||
<image>
|
||||
<use>texture[5]/image</use>
|
||||
</image>
|
||||
<filter>
|
||||
<use>texture[5]/filter</use>
|
||||
</filter>
|
||||
<wrap-s>
|
||||
<use>texture[5]/wrap-s</use>
|
||||
</wrap-s>
|
||||
<wrap-t>
|
||||
<use>texture[5]/wrap-t</use>
|
||||
</wrap-t>
|
||||
<internal-format>
|
||||
<use>texture[5]/internal-format</use>
|
||||
</internal-format>
|
||||
</texture-unit>
|
||||
<texture-unit>
|
||||
<unit>6</unit>
|
||||
<image>
|
||||
<use>texture[6]/image</use>
|
||||
</image>
|
||||
<filter>
|
||||
<use>texture[6]/filter</use>
|
||||
</filter>
|
||||
<wrap-s>
|
||||
<use>texture[6]/wrap-s</use>
|
||||
</wrap-s>
|
||||
<wrap-t>
|
||||
<use>texture[6]/wrap-t</use>
|
||||
</wrap-t>
|
||||
<internal-format>
|
||||
<use>texture[6]/internal-format</use>
|
||||
</internal-format>
|
||||
</texture-unit>
|
||||
|
||||
<program>
|
||||
<vertex-shader>Shaders/water_lightfield.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/water_lightfield.frag</fragment-shader>
|
||||
</program>
|
||||
<!--<uniform>
|
||||
<name>water_reflection</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">0</value>
|
||||
</uniform>-->
|
||||
<uniform>
|
||||
<name>water_normalmap</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">2</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>water_dudvmap</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">3</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>sea_foam</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">5</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>perlin_normalmap</name>
|
||||
<type>sampler-2d</type>
|
||||
<value type="int">6</value>
|
||||
</uniform>
|
||||
<!-- normalmap is .dds-->
|
||||
<uniform>
|
||||
<name>normalmap_dds</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>normalmap_dds</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>saturation</name>
|
||||
<type>float</type>
|
||||
<!--<value>0.4</value>-->
|
||||
<value>
|
||||
<use>saturation</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>WindE</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>windE</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>WindN</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>windN</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>WaveFreq</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>WaveFreq</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>WaveAmp</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>WaveAmp</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>WaveSharp</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>WaveSharp</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>WaveAngle</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>WaveAngle</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>WaveFactor</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>WaveFactor</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>WaveDAngle</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>WaveDAngle</use>
|
||||
</value>
|
||||
</uniform>
|
||||
|
||||
|
||||
|
||||
<!-- BEGIN fog include -->
|
||||
<uniform>
|
||||
<name>visibility</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>visibility</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>avisibility</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>avisibility</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>hazeLayerAltitude</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>lthickness</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>scattering</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>scattering</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>ground_scattering</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>ground_scattering</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>terminator</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>terminator</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>terrain_alt</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>terrain_alt</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>overcast</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>overcast</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>eye_alt</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>eye_alt</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<!-- sea colors -->
|
||||
<uniform>
|
||||
<name>sea_r</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>sea_r</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>sea_g</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>sea_g</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<uniform>
|
||||
<name>sea_b</name>
|
||||
<type>float</type>
|
||||
<value>
|
||||
<use>sea_b</use>
|
||||
</value>
|
||||
</uniform>
|
||||
<!-- END fog include -->
|
||||
</pass>
|
||||
</technique>
|
||||
|
||||
|
||||
<technique n="3">
|
||||
<predicate>
|
||||
<and>
|
||||
|
@ -310,7 +667,7 @@
|
|||
|
||||
<program>
|
||||
<vertex-shader>Shaders/water_lightfield.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/water_lightfield.frag</fragment-shader>
|
||||
<fragment-shader>Shaders/water_lightfield_lr.frag</fragment-shader>
|
||||
</program>
|
||||
<!--<uniform>
|
||||
<name>water_reflection</name>
|
||||
|
|
|
@ -36,13 +36,67 @@
|
|||
<tile-management>METAR</tile-management>
|
||||
</local-weather>
|
||||
</scenario>
|
||||
<scenario>
|
||||
<name type="string">Core high pressure region</name>
|
||||
<metar type="string">XXXX 012345Z 15003KT 19SM FEW072 FEW350 25/07 Q1028 NOSIG</metar>
|
||||
<description type="string">The center of a high pressure region, characterized by descending air and hence only weak cloud development with high visibility.</description>
|
||||
<local-weather>
|
||||
<tile-type>High-pressure-core</tile-type>
|
||||
<tile-management>realistic weather</tile-management>
|
||||
</local-weather>
|
||||
</scenario>
|
||||
<scenario>
|
||||
<name type="string">High pressure region</name>
|
||||
<metar type="string">XXXX 012345Z 15003KT 12SM SCT048 FEW300 20/08 Q1022 NOSIG</metar>
|
||||
<description type="string">A high pressure region, characterized my moderate to strong Cumulus development in the afternoon and fairly good visibility conditions.</description>
|
||||
<local-weather>
|
||||
<tile-type>High-pressure</tile-type>
|
||||
<tile-management>realistic weather</tile-management>
|
||||
</local-weather>
|
||||
</scenario>
|
||||
<scenario>
|
||||
<name type="string">Border of a high pressure region</name>
|
||||
<metar type="string">XXXX 012345Z 15003KT 10SM SCT036 SCT150 17/08 Q1016 NOSIG</metar>
|
||||
<description type="string">The border of a high pressure region, in which the airmass becomes unstable and various convective and stratiform clouds may appear.</description>
|
||||
<local-weather>
|
||||
<tile-type>High-pressure-border</tile-type>
|
||||
<tile-management>realistic weather</tile-management>
|
||||
</local-weather>
|
||||
</scenario>
|
||||
<scenario>
|
||||
<name type="string">Border of a low pressure region</name>
|
||||
<metar type="string">XXXX 012345Z 15003KT 9SM BKN028 SCT090 FEW160 15/08 Q1010 NOSIG</metar>
|
||||
<description type="string">The border of a low pressure region, in which the airmass is unstable and convective clouds start to form layers and merge into stratiform clouds.</description>
|
||||
<local-weather>
|
||||
<tile-type>Low-pressure-border</tile-type>
|
||||
<tile-management>realistic weather</tile-management>
|
||||
</local-weather>
|
||||
</scenario>
|
||||
<scenario>
|
||||
<name type="string">Low pressure region</name>
|
||||
<metar type="string">XXXX 012345Z 15003KT 6SM SHRA BKN024 BKN053 FEW090 13/07 Q1004 NOSIG</metar>
|
||||
<description type="string">A low pressure region, characterized by rising air, widespread formation of stratiform clouds and beginning rain.</description>
|
||||
<local-weather>
|
||||
<tile-type>Low-pressure</tile-type>
|
||||
<tile-management>realistic weather</tile-management>
|
||||
</local-weather>
|
||||
</scenario>
|
||||
<scenario>
|
||||
<name type="string">Core low pressure region</name>
|
||||
<metar type="string">XXXX 012345Z 15003KT 4SM RA OVC020 SCT050 07/02 Q0998 NOSIG</metar>
|
||||
<description type="string">The core of a low pressure region, characterized by overcast clouds, bad visibility on the ground and significant rainfall.</description>
|
||||
<local-weather>
|
||||
<tile-type>Low-pressure-core</tile-type>
|
||||
<tile-management>realistic weather</tile-management>
|
||||
</local-weather>
|
||||
</scenario>
|
||||
<scenario>
|
||||
<name type="string">Fair weather</name>
|
||||
<metar type="string">XXXX 012345Z 15003KT 12SM SCT041 FEW200 20/08 Q1015 NOSIG</metar>
|
||||
<description type="string">A lovely day for trip to your favorite 100$ hamburger airfield</description>
|
||||
<local-weather>
|
||||
<tile-type>High-pressure-core</tile-type>
|
||||
<tile-management>realistic-weather</tile-management>
|
||||
<tile-management>realistic weather</tile-management>
|
||||
</local-weather>
|
||||
</scenario>
|
||||
<scenario>
|
||||
|
@ -55,7 +109,7 @@
|
|||
</description>
|
||||
<local-weather>
|
||||
<tile-type>Thunderstorms</tile-type>
|
||||
<tile-management>realistic-weather</tile-management>
|
||||
<tile-management>repeat tile</tile-management>
|
||||
</local-weather>
|
||||
</scenario>
|
||||
<scenario>
|
||||
|
@ -362,6 +416,7 @@
|
|||
<surface>
|
||||
<scattering type="double" userarchive="n">0.7</scattering>
|
||||
<dust-cover-factor type="double" userarchive="y">0.0</dust-cover-factor>
|
||||
<lichen-cover-factor type="double" userarchive="y">0.0</lichen-cover-factor>
|
||||
<wetness type="double" userarchive="y">0.0</wetness>
|
||||
</surface>
|
||||
</PropertyList>
|
||||
|
|
|
@ -179,6 +179,7 @@
|
|||
<!-- TODO: handle variable winds -->
|
||||
<filter include="layer-heading-offset.xml"/>
|
||||
<filter include="layer-heading-offset.xml">
|
||||
<name>MetarController:layer:wind-from-heading-deg_0</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -192,6 +193,7 @@
|
|||
<output>/environment/config/aloft/entry[0]/wind-from-heading-deg</output>
|
||||
</filter>
|
||||
<filter include="layer-heading-offset.xml">
|
||||
<name>MetarController:layer:wind-from-heading-deg_1</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -205,6 +207,7 @@
|
|||
<output>/environment/config/aloft/entry[1]/wind-from-heading-deg</output>
|
||||
</filter>
|
||||
<filter include="layer-heading-offset.xml">
|
||||
<name>MetarController:layer:wind-from-heading-deg_2</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -218,6 +221,7 @@
|
|||
<output>/environment/config/aloft/entry[2]/wind-from-heading-deg</output>
|
||||
</filter>
|
||||
<filter include="layer-heading-offset.xml">
|
||||
<name>MetarController:layer:wind-from-heading-deg_3</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -231,6 +235,7 @@
|
|||
<output>/environment/config/aloft/entry[3]/wind-from-heading-deg</output>
|
||||
</filter>
|
||||
<filter include="layer-heading-offset.xml">
|
||||
<name>MetarController:layer:wind-from-heading-deg_4</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -246,6 +251,7 @@
|
|||
|
||||
<filter include="layer-speed-change.xml"/>
|
||||
<filter include="layer-speed-change.xml">
|
||||
<name>MetarController:layer:wind-speed-kt_0</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -259,6 +265,7 @@
|
|||
<output>/environment/config/aloft/entry[0]/wind-speed-kt</output>
|
||||
</filter>
|
||||
<filter include="layer-speed-change.xml">
|
||||
<name>MetarController:layer:wind-speed-kt_1</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -272,6 +279,7 @@
|
|||
<output>/environment/config/aloft/entry[1]/wind-speed-kt</output>
|
||||
</filter>
|
||||
<filter include="layer-speed-change.xml">
|
||||
<name>MetarController:layer:wind-speed-kt_2</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -285,6 +293,7 @@
|
|||
<output>/environment/config/aloft/entry[2]/wind-speed-kt</output>
|
||||
</filter>
|
||||
<filter include="layer-speed-change.xml">
|
||||
<name>MetarController:layer:wind-speed-kt_3</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -298,6 +307,7 @@
|
|||
<output>/environment/config/aloft/entry[3]/wind-speed-kt</output>
|
||||
</filter>
|
||||
<filter include="layer-speed-change.xml">
|
||||
<name>MetarController:layer:wind-speed-kt_4</name>
|
||||
<enable>
|
||||
<condition>
|
||||
<property>/environment/metar/valid</property>
|
||||
|
@ -314,24 +324,28 @@
|
|||
<!-- Clouds -->
|
||||
<filter include="clouds-altitude-interpolate.xml"/>
|
||||
<filter include="clouds-altitude-interpolate.xml">
|
||||
<name>MetarController:clouds:altitude_interpolate_0</name>
|
||||
<params>
|
||||
<from>/environment/metar/clouds/layer[1]/elevation-ft</from>
|
||||
<to>/environment/clouds/layer[1]/elevation-ft</to>
|
||||
</params>
|
||||
</filter>
|
||||
<filter include="clouds-altitude-interpolate.xml">
|
||||
<name>MetarController:clouds:altitude_interpolate_1</name>
|
||||
<params>
|
||||
<from>/environment/metar/clouds/layer[2]/elevation-ft</from>
|
||||
<to>/environment/clouds/layer[2]/elevation-ft</to>
|
||||
</params>
|
||||
</filter>
|
||||
<filter include="clouds-altitude-interpolate.xml">
|
||||
<name>MetarController:clouds:altitude_interpolate_2</name>
|
||||
<params>
|
||||
<from>/environment/metar/clouds/layer[3]/elevation-ft</from>
|
||||
<to>/environment/clouds/layer[3]/elevation-ft</to>
|
||||
</params>
|
||||
</filter>
|
||||
<filter include="clouds-altitude-interpolate.xml">
|
||||
<name>MetarController:clouds:altitude_interpolate_3</name>
|
||||
<params>
|
||||
<from>/environment/metar/clouds/layer[4]/elevation-ft</from>
|
||||
<to>/environment/clouds/layer[4]/elevation-ft</to>
|
||||
|
@ -340,42 +354,50 @@
|
|||
|
||||
<filter include="clouds-thickness.xml"/>
|
||||
<filter include="clouds-thickness.xml">
|
||||
<name>MetarController:clouds:thickness_0</name>
|
||||
<input>/environment/metar/clouds/layer[1]/thickness-ft</input>
|
||||
<output>/environment/clouds/layer[1]/thickness-ft</output>
|
||||
</filter>
|
||||
<filter include="clouds-thickness.xml">
|
||||
<name>MetarController:clouds:thickness_1</name>
|
||||
<input>/environment/metar/clouds/layer[2]/thickness-ft</input>
|
||||
<output>/environment/clouds/layer[2]/thickness-ft</output>
|
||||
</filter>
|
||||
<filter include="clouds-thickness.xml">
|
||||
<name>MetarController:clouds:thickness_2</name>
|
||||
<input>/environment/metar/clouds/layer[3]/thickness-ft</input>
|
||||
<output>/environment/clouds/layer[3]/thickness-ft</output>
|
||||
</filter>
|
||||
<filter include="clouds-thickness.xml">
|
||||
<name>MetarController:clouds:thickness_3</name>
|
||||
<input>/environment/metar/clouds/layer[4]/thickness-ft</input>
|
||||
<output>/environment/clouds/layer[4]/thickness-ft</output>
|
||||
</filter>
|
||||
|
||||
<filter include="clouds-coverage.xml"/>
|
||||
<filter include="clouds-coverage.xml">
|
||||
<name>MetarController:clouds:coverage_0</name>
|
||||
<params>
|
||||
<from>/environment/metar/clouds/layer[1]/coverage-type</from>
|
||||
<to>environment/clouds/layer[1]/coverage-type</to>
|
||||
</params>
|
||||
</filter>
|
||||
<filter include="clouds-coverage.xml">
|
||||
<name>MetarController:clouds:coverage_1</name>
|
||||
<params>
|
||||
<from>/environment/metar/clouds/layer[2]/coverage-type</from>
|
||||
<to>environment/clouds/layer[2]/coverage-type</to>
|
||||
</params>
|
||||
</filter>
|
||||
<filter include="clouds-coverage.xml">
|
||||
<name>MetarController:clouds:coverage_2</name>
|
||||
<params>
|
||||
<from>/environment/metar/clouds/layer[3]/coverage-type</from>
|
||||
<to>environment/clouds/layer[3]/coverage-type</to>
|
||||
</params>
|
||||
</filter>
|
||||
<filter include="clouds-coverage.xml">
|
||||
<name>MetarController:clouds:coverage_3</name>
|
||||
<params>
|
||||
<from>/environment/metar/clouds/layer[4]/coverage-type</from>
|
||||
<to>environment/clouds/layer[4]/coverage-type</to>
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
<PropertyList>
|
||||
|
||||
<name>Logitech Attack 3</name>
|
||||
<name>Logitech Logitech Attack 3</name>
|
||||
|
||||
<axis n="0">
|
||||
|
|
|
@ -1282,6 +1282,155 @@
|
|||
<tree-width-m>12.0</tree-width-m>
|
||||
</material>
|
||||
|
||||
|
||||
<!-- REGIONAL DEFINITIONS - SOUTH AMERICAN RAINFOREST BELT -->
|
||||
|
||||
|
||||
<material include="Materials/regions/tropical_south_america.xml">
|
||||
<name>EvergreenBroadCover</name>
|
||||
<name>EvergreenForest</name>
|
||||
<effect>Effects/forest</effect>
|
||||
<texture-set>
|
||||
<texture>Terrain/rainforest-hawaii.png</texture>
|
||||
<texture n="11">Terrain/rainforest-hawaii.png</texture>
|
||||
<texture n="12">Terrain/dirtrock.png</texture>
|
||||
</texture-set>
|
||||
<xsize>2000</xsize>
|
||||
<ysize>2000</ysize>
|
||||
<light-coverage>10000000.0</light-coverage>
|
||||
<wood-coverage>4000.0</wood-coverage>
|
||||
<tree-texture>Trees/tropical-summer.png</tree-texture>
|
||||
<tree-varieties>8</tree-varieties>
|
||||
<tree-range-m alias="/params/forest/tree-range-m"/>
|
||||
<tree-height-m>35.0</tree-height-m>
|
||||
<tree-width-m>30.0</tree-width-m>
|
||||
<rolling-friction>1</rolling-friction>
|
||||
<bumpiness>1</bumpiness>
|
||||
</material>
|
||||
|
||||
|
||||
<material include="Materials/regions/tropical_south_america.xml">
|
||||
<name>HerbTundraCover</name>
|
||||
<name>HerbTundra</name>
|
||||
<effect>Effects/herbtundra</effect>
|
||||
<texture-set>
|
||||
<texture>Terrain/herbtundra.png</texture>
|
||||
<texture n="11">Terrain/grass_hires.png</texture>
|
||||
<texture n="12">Terrain/dirtrock.png</texture>
|
||||
</texture-set>
|
||||
<xsize>2000</xsize>
|
||||
<ysize>2000</ysize>
|
||||
<light-coverage>4000000.0</light-coverage>
|
||||
<diffuse>
|
||||
<r>0.93</r>
|
||||
<g>0.95</g>
|
||||
<b>0.93</b>
|
||||
<a>1.0</a>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<r>0.1</r>
|
||||
<g>0.12</g>
|
||||
<b>0.1</b>
|
||||
<a>1.0</a>
|
||||
</specular>
|
||||
<shininess>1.2</shininess>
|
||||
<solid>1</solid>
|
||||
<friction-factor>0.8</friction-factor>
|
||||
<rolling-friction>0.1</rolling-friction>
|
||||
<bumpiness>0.15</bumpiness>
|
||||
<load-resistance>1e30</load-resistance>
|
||||
<wood-coverage>70000.0</wood-coverage>
|
||||
<tree-texture>Trees/tropical-summer.png</tree-texture>
|
||||
<tree-varieties>8</tree-varieties>
|
||||
<tree-range-m alias="/params/forest/tree-range-m"/>
|
||||
<tree-height-m>25.0</tree-height-m>
|
||||
<tree-width-m>18.0</tree-width-m>
|
||||
</material>
|
||||
|
||||
<material include="Materials/regions/tropical_south_america.xml">
|
||||
<name>MixedCropPastureCover</name>
|
||||
<name>MixedCrop</name>
|
||||
<name>ComplexCrop</name>
|
||||
<texture-set>
|
||||
<texture>Terrain/shrub1.png</texture>
|
||||
<texture n="11">Terrain/grass_hires.png</texture>
|
||||
<texture n="12">Terrain/dirtrock.png</texture>
|
||||
</texture-set>
|
||||
<xsize>2000</xsize>
|
||||
<ysize>2000</ysize>
|
||||
<light-coverage>2000000.0</light-coverage>
|
||||
<solid>1</solid>
|
||||
<friction-factor>0.9</friction-factor>
|
||||
<rolling-friction>0.1</rolling-friction>
|
||||
<bumpiness>0.7</bumpiness>
|
||||
<load-resistance>1e30</load-resistance>
|
||||
<wood-coverage>10000.0</wood-coverage>
|
||||
<tree-texture>Trees/tropical-summer.png</tree-texture>
|
||||
<tree-varieties>8</tree-varieties>
|
||||
<tree-range-m alias="/params/forest/tree-range-m"/>
|
||||
<tree-height-m>20.0</tree-height-m>
|
||||
<tree-width-m>12.0</tree-width-m>
|
||||
</material>
|
||||
|
||||
<material include="Materials/regions/tropical_south_america.xml">
|
||||
<effect>Effects/crop</effect>
|
||||
<name>DryCropPastureCover</name>
|
||||
<name>DryCrop</name>
|
||||
<texture-set>
|
||||
<texture>Terrain/tundra-hawaii-green.png</texture>
|
||||
<texture n="11">Terrain/grass_hires.png</texture>
|
||||
<texture n="12">Terrain/dirtrock.png</texture>
|
||||
</texture-set>
|
||||
<xsize>2000</xsize>
|
||||
<ysize>2000</ysize>
|
||||
<solid>1</solid>
|
||||
<friction-factor>0.9</friction-factor>
|
||||
<rolling-friction>0.1</rolling-friction>
|
||||
<bumpiness>0.6</bumpiness>
|
||||
<load-resistance>1e30</load-resistance>
|
||||
<light-coverage>2000000.0</light-coverage>
|
||||
<wood-coverage>50000.0</wood-coverage>
|
||||
<tree-texture>Trees/tropical-summer.png</tree-texture>
|
||||
<tree-varieties>8</tree-varieties>
|
||||
<tree-range-m alias="/params/forest/tree-range-m"/>
|
||||
<tree-height-m>20.0</tree-height-m>
|
||||
<tree-width-m>12.0</tree-width-m>
|
||||
</material>
|
||||
|
||||
<material include="Materials/regions/tropical_south_america.xml">
|
||||
<name>GrassCover</name>
|
||||
<name>BareTundraCover</name>
|
||||
<name>MixedTundraCover</name>
|
||||
<name>Cemetery</name>
|
||||
<effect>Effects/landmass-nowood</effect>
|
||||
<texture-set>
|
||||
<texture>Terrain/tundra-hawaii-green.png</texture>
|
||||
<texture n="11">Terrain/rainforest-hawaii.png</texture>
|
||||
<texture n="12">Terrain/dirtrock.png</texture>
|
||||
</texture-set>
|
||||
<xsize>2000</xsize>
|
||||
<ysize>2000</ysize>
|
||||
<light-coverage>4000000.0</light-coverage>
|
||||
<diffuse>
|
||||
<r>0.93</r>
|
||||
<g>0.95</g>
|
||||
<b>0.93</b>
|
||||
<a>1.0</a>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<r>0.1</r>
|
||||
<g>0.12</g>
|
||||
<b>0.1</b>
|
||||
<a>1.0</a>
|
||||
</specular>
|
||||
<shininess>1.2</shininess>
|
||||
<solid>1</solid>
|
||||
<friction-factor>0.7</friction-factor>
|
||||
<rolling-friction>0.1</rolling-friction>
|
||||
<bumpiness>0.15</bumpiness>
|
||||
<load-resistance>1e30</load-resistance>
|
||||
</material>
|
||||
|
||||
<!-- DEFAULT SUMMER DEFINITIONS -->
|
||||
|
||||
<material>
|
||||
|
|
27
Materials/regions/tropical_south_america.xml
Normal file
27
Materials/regions/tropical_south_america.xml
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- General settings for all tropical South American materials -->
|
||||
<PropertyList>
|
||||
<!-- Define tropical South America as a box with given latitude/longitude -->
|
||||
<condition>
|
||||
<and>
|
||||
<greater-than>
|
||||
<property>position/longitude-deg</property>
|
||||
<value>-90.0</value>
|
||||
</greater-than>
|
||||
<less-than>
|
||||
<property>position/longitude-deg</property>
|
||||
<value>-30.0</value>
|
||||
</less-than>
|
||||
<greater-than>
|
||||
<property>position/latitude-deg</property>
|
||||
<value>-15.0</value>
|
||||
</greater-than>
|
||||
<less-than>
|
||||
<property>position/latitude-deg</property>
|
||||
<value>15.0</value>
|
||||
</less-than>
|
||||
</and>
|
||||
</condition>
|
||||
|
||||
|
||||
</PropertyList>
|
|
@ -60,5 +60,10 @@ var PropertyElement = {
|
|||
return node.getValue();
|
||||
else
|
||||
return default;
|
||||
}
|
||||
},
|
||||
getBool: func(key)
|
||||
{
|
||||
me._node.getNode(key, 1).getBoolValue();
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -218,10 +218,13 @@ var Element = {
|
|||
{
|
||||
me.setBool("visible", visible);
|
||||
},
|
||||
getVisible: func me.getBool("visible"),
|
||||
# Hide element (Shortcut for setVisible(0))
|
||||
hide: func me.setVisible(0),
|
||||
# Show element (Shortcut for setVisible(1))
|
||||
show: func me.setVisible(1),
|
||||
# Toggle element visibility
|
||||
toggleVisibility: func me.setVisible( !me.getVisible() ),
|
||||
#
|
||||
setGeoPosition: func(lat, lon)
|
||||
{
|
||||
|
@ -266,15 +269,18 @@ var Element = {
|
|||
getBoundingBox: func()
|
||||
{
|
||||
var bb = me._node.getNode("bounding-box");
|
||||
var min_x = bb.getNode("min-x").getValue();
|
||||
|
||||
if( min_x != nil )
|
||||
return [ min_x,
|
||||
bb.getNode("min-y").getValue(),
|
||||
bb.getNode("max-x").getValue(),
|
||||
bb.getNode("max-y").getValue() ];
|
||||
else
|
||||
return [0, 0, 0, 0];
|
||||
if( bb != nil )
|
||||
{
|
||||
var min_x = bb.getNode("min-x").getValue();
|
||||
|
||||
if( min_x != nil )
|
||||
return [ min_x,
|
||||
bb.getNode("min-y").getValue(),
|
||||
bb.getNode("max-x").getValue(),
|
||||
bb.getNode("max-y").getValue() ];
|
||||
}
|
||||
|
||||
return [0, 0, 0, 0];
|
||||
},
|
||||
# Set transformation center (currently only used for rotation)
|
||||
setCenter: func()
|
||||
|
|
23
Nasal/canvas/design.txt
Normal file
23
Nasal/canvas/design.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
Nothing set in stone yet, we'll document things once the API becomes more stable and once it has been used in several dialogs and instruments
|
||||
|
||||
At the moment, this implements the notion of a "LayeredMap", a LayeredMap is a conventional Canvas Map which has support for easily managing "Layers",
|
||||
which are internally mapped to Canvas Groups. Each Group's "visible" property is managed by the LayeredMap, so that layers can be easily
|
||||
toggled on/off, i.e. via checkboxes.
|
||||
|
||||
Basically, the idea is this, we'll have a MVC (Model/View/Controller) setup, where:
|
||||
- the Model is mapped to the drawable's meta information (i.e. position)
|
||||
- the View is mapped to a conventional canvas group
|
||||
- the Controller is mapped to a bunch of property/timer callbacks to control the Model/View
|
||||
|
||||
|
||||
|
||||
|
||||
Model = PositionedSource
|
||||
View = Canvas
|
||||
Controller = control properties (zoom, range etc)
|
||||
|
||||
LayerElement = callback to create a canvas group
|
||||
Layer = canvas.Group
|
||||
|
||||
Map -> LayeredMap -> GenericMap -> AirportMap
|
||||
|
105
Nasal/canvas/generic-canvas-map.xml
Normal file
105
Nasal/canvas/generic-canvas-map.xml
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
generic-canvas.map XML:
|
||||
- to be used by dialogs and instruments to add a generic map (navaids, fixes, airports etc)
|
||||
- with each feature put on a separate layer (canvas group)
|
||||
- each layer being controllable via a boolean property
|
||||
|
||||
NOTE: This is still work in progress, and will be significantly refactored in the time to come
|
||||
|
||||
Current requirements: (these are subject to change)
|
||||
|
||||
Dialogs wanting to use this, MUST:
|
||||
|
||||
- set DIALOG_CANVAS in open block
|
||||
- provide a helper function dialog_property(p) to return a property appended to the dialog root in /sim/gui/dialogs/FOO/
|
||||
- to set up layer-checkboxes automatically, use canvas.GenericMap.setupGUICheckboxes(DIALOG_CANVAS, gui_group)
|
||||
|
||||
For example, add this to your dialogs Nasal/open block in "foo.xml":
|
||||
var dialog_name = "foo";
|
||||
var dialog_property = func(p) return "/sim/gui/dialogs/foo/"~p;
|
||||
var DIALOG_CANVAS = gui.findElementByName(cmdarg(), "airport-selection");
|
||||
canvas.GenericMap.setupGUICheckboxes(DIALOG_CANVAS, "canvas-control");
|
||||
|
||||
TODO: use a single "InitCanvasMapSupport();" helper
|
||||
|
||||
In the close block, you'll want to call "map.cleanup_listeners()" at the moment
|
||||
|
||||
-->
|
||||
<PropertyList>
|
||||
<!--FIXME: move somewhere else, this is GUI specific and not useful for canvas maps shown as instruments! -->
|
||||
<checkbox-toggle-template>
|
||||
<name></name>
|
||||
<label></label>
|
||||
<property></property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
<object-name></object-name>
|
||||
</binding>
|
||||
</checkbox-toggle-template>
|
||||
|
||||
<!-- will be procedurally added to the dialog -->
|
||||
<zoom-template>
|
||||
<button>
|
||||
<name>zoomout</name>
|
||||
<legend>-</legend>
|
||||
<pref-width>22</pref-width>
|
||||
<pref-height>22</pref-height>
|
||||
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property></property>
|
||||
<min>0</min>
|
||||
<step>-1</step>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<text>
|
||||
<label>MMMM</label>
|
||||
<halign>center</halign>
|
||||
<format>Zoom %d</format>
|
||||
<property></property>
|
||||
<live>true</live>
|
||||
</text>
|
||||
|
||||
<button>
|
||||
<name>zoomin</name>
|
||||
<legend>+</legend>
|
||||
<pref-width>22</pref-width>
|
||||
<pref-height>22</pref-height>
|
||||
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property></property>
|
||||
<step>1</step>
|
||||
<max></max> <!-- FIXME: compute dynamically via Nasal size() or just a property-->
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<empty><stretch>true</stretch></empty>
|
||||
|
||||
</zoom-template>
|
||||
|
||||
<nasal>
|
||||
<load><![CDATA[
|
||||
var my_canvas = canvas.get(cmdarg());
|
||||
my_canvas.setColorBackground(0.2, 0.5, 0.2, 0.5); #TODO: support customization in XML
|
||||
|
||||
var root = my_canvas.createGroup();
|
||||
# the top level AirportMap element uses a "GenericMap" now:
|
||||
|
||||
#TODO: features should be procedurally enabled via params (WIP)
|
||||
#TODO: use generic Map and instantiate via XML
|
||||
var map = canvas.GenericMap.new(parent:root, name:dialog_name) # FIXME: We shouldn't be using AirportMap here:
|
||||
# we need a high level wrapper that can instantiate
|
||||
# all sorts of maps, not just AirportMaps
|
||||
.setTranslation(300, 200) # TODO: move to Map class ctor!
|
||||
.setupZoom( dialog:DIALOG_CANVAS ) # TODO: make zooming configurable for non GUI use
|
||||
.pickupFeatures (DIALOG_CANVAS); # set up the features specified in the XML file
|
||||
|
||||
# FIXME: resource cleanup (listeners!)
|
||||
update_info();
|
||||
]]>
|
||||
</load>
|
||||
</nasal>
|
||||
</PropertyList>
|
|
@ -1,3 +1,89 @@
|
|||
###
|
||||
# map.nas - provide a high level method to create typical maps in FlightGear (airports, navaids, fixes and waypoints) for both, the GUI and instruments
|
||||
# implements the notion of a "layer" by using canvas groups and adding geo-referenced elements to a layer
|
||||
# layered maps are linked to boolean properties so that visibility can be easily toggled (GUI checkboxes or cockpit hotspots)
|
||||
# without having to redraw other layers
|
||||
#
|
||||
# GOALS: have a single Nasal/Canvas wrapper for all sort of maps in FlightGear, that can be easily shared and reused for different purposes
|
||||
#
|
||||
# DESIGN: ... is slowly evolving, but still very much beta for the time being
|
||||
#
|
||||
# API: not yet documented, but see eventually design.txt (will need to add doxygen-strings then)
|
||||
#
|
||||
# PERFORMANCE: will be improved, probabaly by moving some features to C++ space and optimizing things there
|
||||
#
|
||||
#
|
||||
# ISSUES: just look for the FIXME and TODO strings - currently, the priority is to create an OOP/MVC design with less specialized code in XML files
|
||||
#
|
||||
#
|
||||
# ROADMAP: Generalize this further, so that:
|
||||
#
|
||||
# - it can be easily reused
|
||||
# - use a MVC approach, where layer-specific data is provided by a Model object
|
||||
# - other dialogs can use this without tons of custom code (airports.xml, route-manager.xml, map-canvas.xml)
|
||||
# - generalize this further so that it can be used by instruments
|
||||
# - implement additional layers (tcas, wxradar, agradar) - especially expose the required data to Nasal
|
||||
# - implement better GUI support (events) so that zooming/panning via mouse can be supported
|
||||
# - make the whole thing styleable
|
||||
#
|
||||
# - keep track of things getting added here and decide if they should better move to the core canvas module or the C++ code
|
||||
#
|
||||
#
|
||||
# C++ RFEs:
|
||||
# - overload findNavaidsWithinRange() to support an optional position argument, so that arbitrary navaids can be looked up
|
||||
# - add Nasal extension function to get scenery vector data (landclass)
|
||||
# -
|
||||
# -
|
||||
#
|
||||
|
||||
|
||||
|
||||
var DEBUG=0;
|
||||
if (DEBUG) {
|
||||
var benchmark = debug.benchmark;
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
var benchmark = func(label, code) code(); # NOP
|
||||
}
|
||||
|
||||
var assert = func(label, expr) expr and die(label);
|
||||
|
||||
# Mapping from surface codes to #TODO: make this XML-configurable
|
||||
var SURFACECOLORS = {
|
||||
1 : { type: "asphalt", r:0.2, g:0.2, b:0.2 },
|
||||
2 : { type: "concrete", r:0.3, g:0.3, b:0.3 },
|
||||
3 : { type: "turf", r:0.2, g:0.5, b:0.2 },
|
||||
4 : { type: "dirt", r:0.4, g:0.3, b:0.3 },
|
||||
5 : { type: "gravel", r:0.35, g:0.3, b:0.3 },
|
||||
# Helipads
|
||||
6 : { type: "asphalt", r:0.2, g:0.2, b:0.2 },
|
||||
7 : { type: "concrete", r:0.3, g:0.3, b:0.3 },
|
||||
8 : { type: "turf", r:0.2, g:0.5, b:0.2 },
|
||||
9 : { type: "dirt", r:0.4, g:0.3, b:0.3 },
|
||||
0 : { type: "gravel", r:0.35, g:0.3, b:0.3 },
|
||||
};
|
||||
|
||||
|
||||
###
|
||||
# ALL LayeredMap "draws" go through this wrapper, which makes it easy to check what's going on:
|
||||
var draw_layer = func(layer, callback, lod) {
|
||||
var name= layer._view.get("id");
|
||||
# print("Canvas:Draw op triggered"); # just to make sure that we are not adding unnecessary data when checking/unchecking a checkbox
|
||||
if (DEBUG and name=="taxiways") fgcommand("profiler-start"); #without my patch, this is a no op, so no need to disable
|
||||
#print("Work items:", size(layer._model._elements));
|
||||
benchmark("Drawing Layer:"~layer._view.get("id"), func
|
||||
foreach(var element; layer._model._elements) {
|
||||
#print(typeof(layer._view));
|
||||
#debug.dump(layer._view);
|
||||
callback(layer._view, element, lod); # ISSUE here
|
||||
});
|
||||
if (! layer._model.hasData() ) print("Layer was EMPTY:", name);
|
||||
if (DEBUG and name=="taxiways") fgcommand("profiler-stop");
|
||||
layer._drawn=1; #TODO: this should be encapsulated
|
||||
}
|
||||
|
||||
# Runway
|
||||
#
|
||||
var Runway = {
|
||||
|
@ -29,154 +115,466 @@ var Runway = {
|
|||
}
|
||||
};
|
||||
|
||||
# AirportMap
|
||||
var make = func return {parents:arg};
|
||||
|
||||
##
|
||||
# TODO: Create a cache to reuse layers and layer data (i.e. runways)
|
||||
|
||||
|
||||
##
|
||||
# Todo: wrap parsesvg and return a function that memoizes the created canvas group, so that svg files only need to be parsed once
|
||||
#
|
||||
var AirportMap = {
|
||||
# Create AirportMap from hash
|
||||
#
|
||||
# @param apt Hash containing airport data as returned from airportinfo()
|
||||
new: func(apt)
|
||||
{
|
||||
return {
|
||||
parents: [AirportMap],
|
||||
_apt: apt
|
||||
};
|
||||
},
|
||||
# Build the graphical representation of the represented airport
|
||||
#
|
||||
# @param layer_runways canvas.Group to attach airport map to
|
||||
build: func(layer_runways)
|
||||
{
|
||||
var rws_done = {};
|
||||
|
||||
me.grp_apt = layer_runways.createChild("group", "apt-" ~ me._apt.id);
|
||||
##
|
||||
# TODO: Implement a real MVC design for "LayeredMaps" that have:
|
||||
# - a "DataProvider" (i.e. Positioned objects)
|
||||
# - a View (i.e. a Canvas)
|
||||
# - a controller (i.e. input/output properties)
|
||||
#
|
||||
var MapModel = {}; # navaids, waypoints, fixes etc
|
||||
MapModel.new = func make(MapModel);
|
||||
|
||||
foreach(var rw; keys(me._apt.runways))
|
||||
{
|
||||
var is_heli = substr(rw, 0, 1) == "H";
|
||||
var rw_dir = is_heli ? nil : int(substr(rw, 0, 2));
|
||||
var MapView = {}; # the canvas view, including a layer for each feature
|
||||
MapView.new = func make(MapView);
|
||||
|
||||
var rw_rec = "";
|
||||
var thresh_rec = 0;
|
||||
if( rw_dir != nil )
|
||||
{
|
||||
rw_rec = sprintf("%02d", math.mod(rw_dir - 18, 36));
|
||||
if( size(rw) == 3 )
|
||||
{
|
||||
var map_rec = {
|
||||
"R": "L",
|
||||
"L": "R",
|
||||
"C": "C"
|
||||
};
|
||||
rw_rec ~= map_rec[substr(rw, 2)];
|
||||
}
|
||||
var MapController = {}; # the property tree interface to manipulate the model/view via properties
|
||||
MapController.new = func make(MapController);
|
||||
|
||||
if( rws_done[rw_rec] != nil )
|
||||
continue;
|
||||
var LazyView = {}; # Gets drawables on demand from the model - via property toggle
|
||||
|
||||
var rw_rec = me._apt.runways[rw_rec];
|
||||
if( rw_rec != nil )
|
||||
thresh_rec = rw_rec.threshold;
|
||||
}
|
||||
var DataProvider = {};
|
||||
DataProvider.new = func make(DataProvider);
|
||||
|
||||
rws_done[rw] = 1;
|
||||
###
|
||||
# for airports, navaids, fixes, waypoints etc
|
||||
var PositionedProvider = {};
|
||||
PositionedProvider.new = func make(DataProvider, PositionedProvider);
|
||||
|
||||
rw = me._apt.runways[rw];
|
||||
var icon_rw =
|
||||
me.grp_apt.createChild("path", "runway-" ~ rw.id)
|
||||
.setStrokeLineWidth(0.5)
|
||||
.setColor(1.0,1.0,1.0)
|
||||
.setColorFill(0.2, 0.2, 0.2);
|
||||
##
|
||||
# Drawable
|
||||
#
|
||||
|
||||
var rwy = Runway.new(rw);
|
||||
var beg_thr = rwy.pointOffCenterline(rw.threshold);
|
||||
var beg_thr1 = rwy.pointOffCenterline(rw.threshold, 0.5 * rw.width);
|
||||
var beg_thr2 = rwy.pointOffCenterline(rw.threshold, -0.5 * rw.width);
|
||||
var beg1 = rwy.pointOffCenterline(0, 0.5 * rw.width);
|
||||
var beg2 = rwy.pointOffCenterline(0, -0.5 * rw.width);
|
||||
## LayerElement (UNUSED ATM):
|
||||
# for runways, navaids, fixes, waypoints etc
|
||||
# TODO: we should differentiate between "fairly static" vs. "dynamic" layers - i.e. navaids vs. traffic
|
||||
var LayerElement = {_drawable:nil};
|
||||
LayerElement.new = func(drawable) {
|
||||
var temp = make(LayerElement);
|
||||
temp._drawable=drawable;
|
||||
return temp;
|
||||
}
|
||||
# a drawable is either a Nasal callback or a scalar, i.e. a path to an SVG file
|
||||
LayerElement.draw = func(group) {
|
||||
(typeof(me._drawable)=='func') and drawable(group) or canvas.parsesvg(group,_drawable);
|
||||
}
|
||||
|
||||
var end_thr = rwy.pointOffCenterline(rw.length - thresh_rec);
|
||||
var end_thr1 = rwy.pointOffCenterline(rw.length - thresh_rec, 0.5 * rw.width);
|
||||
var end_thr2 = rwy.pointOffCenterline(rw.length - thresh_rec, -0.5 * rw.width);
|
||||
var end1 = rwy.pointOffCenterline(rw.length, 0.5 * rw.width);
|
||||
var end2 = rwy.pointOffCenterline(rw.length, -0.5 * rw.width);
|
||||
# For static targets like Navaids, Fixes - i.e. geographic position doesn't change
|
||||
var StaticLayerElement = {};
|
||||
|
||||
icon_rw.setDataGeo
|
||||
(
|
||||
[ canvas.Path.VG_MOVE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_CLOSE_PATH ],
|
||||
[ beg1[0], beg1[1],
|
||||
beg2[0], beg2[1],
|
||||
end2[0], end2[1],
|
||||
end1[0], end1[1] ]
|
||||
);
|
||||
# For moving targets such as aircraft, multiplayer, ai traffic etc
|
||||
var DynamicLayerElement = {};
|
||||
|
||||
if( rw.length / rw.width > 3 and !is_heli )
|
||||
{
|
||||
# only runways which are much longer than wide are
|
||||
# real runways, otherwise it's probably a heliport.
|
||||
var icon_cl =
|
||||
me.grp_apt.createChild("path", "centerline")
|
||||
.setStrokeLineWidth(0.5)
|
||||
.setColor(1,1,1)
|
||||
.setStrokeDashArray([15, 10]);
|
||||
var AnimatedLayerElement = {};
|
||||
|
||||
icon_cl.setDataGeo
|
||||
(
|
||||
[ canvas.Path.VG_MOVE_TO,
|
||||
canvas.Path.VG_LINE_TO ],
|
||||
[ beg_thr[0], beg_thr[1],
|
||||
end_thr[0], end_thr[1] ]
|
||||
);
|
||||
# for elements whose appearance may change depending on selected range (i.e. LOD)
|
||||
var RangeAwareLayerElement = {};
|
||||
|
||||
var icon_thr =
|
||||
me.grp_apt.createChild("path", "threshold")
|
||||
.setStrokeLineWidth(1.5)
|
||||
.setColor(1,1,1);
|
||||
|
||||
icon_thr.setDataGeo
|
||||
(
|
||||
[ canvas.Path.VG_MOVE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_MOVE_TO,
|
||||
canvas.Path.VG_LINE_TO ],
|
||||
[ beg_thr1[0], beg_thr1[1],
|
||||
beg_thr2[0], beg_thr2[1],
|
||||
end_thr1[0], end_thr1[1],
|
||||
end_thr2[0], end_thr2[1] ]
|
||||
);
|
||||
}
|
||||
}
|
||||
##
|
||||
# A layer model is just a wrapper for a vector with elements
|
||||
# either updated via a timer or via a listener
|
||||
|
||||
foreach(var park; me._apt.parking())
|
||||
{
|
||||
var icon_park =
|
||||
me.grp_apt.createChild("text", "parking-" ~ park.name)
|
||||
.setDrawMode( canvas.Text.ALIGNMENT
|
||||
+ canvas.Text.TEXT )
|
||||
.setText(park.name)
|
||||
.setFont("LiberationFonts/LiberationMono-Bold.ttf")
|
||||
.setGeoPosition(park.lat, park.lon)
|
||||
.setFontSize(15, 1.3);
|
||||
}
|
||||
|
||||
var icon_tower =
|
||||
me.grp_apt.createChild("path", "tower")
|
||||
.setStrokeLineWidth(1)
|
||||
.setScale(1.5)
|
||||
.setColor(0.2,0.2,1.0)
|
||||
.moveTo(-3, 0)
|
||||
.vert(-10)
|
||||
.line(-3, -10)
|
||||
.horiz(12)
|
||||
.line(-3, 10)
|
||||
.vert(10);
|
||||
|
||||
var pos = me._apt.tower();
|
||||
icon_tower.setGeoPosition(pos.lat, pos.lon);
|
||||
|
||||
}
|
||||
var LayerModel = {_elements:[], _view:, _controller: };
|
||||
LayerModel.new = func make(LayerModel);
|
||||
LayerModel.clear = func me._elements = [];
|
||||
LayerModel.push = func (e) append(me._elements, e);
|
||||
LayerModel.get = func me._elements;
|
||||
LayerModel.update = func;
|
||||
LayerModel.hasData = func size(me. _elements);
|
||||
LayerModel.setView = func(v) me._view=v;
|
||||
LayerModel.setController = func(c) me._controller=c;
|
||||
|
||||
|
||||
var LayerController = {};
|
||||
LayerController.new = func make(LayerController);
|
||||
|
||||
##
|
||||
# use timers to update the model/view (canvas)
|
||||
var TimeBasedLayerController = {};
|
||||
LayerController.new = func make(TimeBasedLayerController);
|
||||
|
||||
##
|
||||
# use listeners to update the model/view (canvas)
|
||||
#
|
||||
var ListenerBasedLayerController = {};
|
||||
ListenerBasedLayerController.new = func make(ListenerBasedLayerController);
|
||||
|
||||
|
||||
##
|
||||
# Uses, both, listeners and timers to update the model/view (canvas)
|
||||
#
|
||||
|
||||
var HybridLayerController = {};
|
||||
HybridLayerController.new = func make(HybridLayerController);
|
||||
|
||||
var ModelEvents = {INIT:, RESET:, UPDATE:};
|
||||
var ViewEvents = {INIT:, RESET:, UPDATE:};
|
||||
var ControllerEvents = {INIT:, RESET: , UPDATE:, ZOOM:, PAN:, };
|
||||
|
||||
|
||||
##
|
||||
# A layer is mapped to a canvas group
|
||||
# Layers are linked to a single boolean property to toggle them on/off
|
||||
var Layer = { _model: ,
|
||||
_view: ,
|
||||
_controller: ,
|
||||
_drawn:0,
|
||||
};
|
||||
|
||||
Layer.new = func(group, name, model) {
|
||||
#print("Setting up new Layer:", name);
|
||||
var m = make(Layer);
|
||||
m._model = model.new();
|
||||
#print("Model name is:", m._model.name);
|
||||
m._view = group.createChild("group",name);
|
||||
m.name = name; #FIXME: not needed, there's already _view.get("id")
|
||||
return m;
|
||||
}
|
||||
|
||||
Layer.hide = func me._view.setVisible(0);
|
||||
Layer.show = func me._view.setVisible(1);
|
||||
#TODO: Unify toggle and update methods - and support lazy drawing (make it optional!)
|
||||
Layer.toggle = func {
|
||||
# print("Toggling layer");
|
||||
var checkbox = getprop(me.display_layer);
|
||||
if(checkbox and !me._drawn) {
|
||||
# print("Lazy drawing");
|
||||
me.draw();
|
||||
}
|
||||
|
||||
#var state= me._view.getBool("visible");
|
||||
#print("Toggle layer visibility ",me.display_layer," checkbox is", checkbox);
|
||||
#print("Layer id is:", me._view.get("id"));
|
||||
#print("Drawn is:", me._drawn);
|
||||
checkbox?me._view.setVisible(1) : me._view.setVisible(0);
|
||||
}
|
||||
Layer.reset = func {
|
||||
me._view.removeAllChildren(); # clear the "real" canvas drawables
|
||||
me._model.clear(); # the vector is used for lazy rendering
|
||||
assert("Model not emptied during layer reset!", me._model.hasData() );
|
||||
me._drawn = 0;
|
||||
}
|
||||
#TODO: Unify toggle and update
|
||||
Layer.update = func {
|
||||
# print("Layer update: Check if layer is visible, if so, draw");
|
||||
if (! getprop(me.display_layer)) return; # checkbox for layer not set
|
||||
if (!me._model.hasData() ) return; # no data available
|
||||
# print("Trying to draw");
|
||||
me.draw();
|
||||
}
|
||||
|
||||
Layer.setDraw = func(callback) me.draw = callback;
|
||||
Layer.setController = func(c) me._controller=c; # TODO: implement
|
||||
Layer.setModel = func(m) nil; # TODO: implement
|
||||
|
||||
|
||||
##TODO: differentiate between layers with a single object (i.e. aircraft) and multiple objects (airports)
|
||||
|
||||
##
|
||||
# We may need to display some stuff that isn't strictly a geopgraphic feature, but just a chart feature
|
||||
#
|
||||
var CartographicLayer = {};
|
||||
|
||||
#TODO:
|
||||
var InteractiveLayer = {};
|
||||
|
||||
###
|
||||
# PositionedLayer
|
||||
#
|
||||
# layer of positioned objects (i.e. have lat,lon,alt)
|
||||
#
|
||||
var PositionedLayer = {};
|
||||
PositionedLayer.new = func() {
|
||||
make( Layer.new() , PositionedLayer );
|
||||
}
|
||||
|
||||
|
||||
###
|
||||
# CachedLayer
|
||||
#
|
||||
# when re-centering on an airport already loaded, we don't want to reload it
|
||||
# but change the reference point and load missing airports
|
||||
|
||||
var CachedLayer = {};
|
||||
|
||||
##
|
||||
#
|
||||
var AirportProvider = {};
|
||||
AirportProvider.new = func make(AirportProvider);
|
||||
AirportProvider.get = func {
|
||||
return airportinfo("ksfo");
|
||||
}
|
||||
|
||||
### Data Providers (preparation for MVC version):
|
||||
# TODO: should use the LayerModel class
|
||||
#
|
||||
|
||||
##
|
||||
# Manage a bunch of layers
|
||||
#
|
||||
|
||||
var LayerManager = {};
|
||||
|
||||
# WXR ?
|
||||
|
||||
# TODO: Stub
|
||||
var MapBehavior = {};
|
||||
MapBehavior.new = make(MapBehavior);
|
||||
MapBehavior.zoom = func;
|
||||
MapBehavior.center = func;
|
||||
|
||||
##
|
||||
# A layered map consists of several layers
|
||||
# TODO: Support nested LayeredMaps, where a LayeredMap may contain other LayeredMaps
|
||||
# TODO: use MapBehavior here and move the zoom/refpos methods there, so that map behavior can be easily customized
|
||||
var LayeredMap = { ranges:[],
|
||||
zoom_property:nil, listeners:[],
|
||||
update_property:nil, layers:[],
|
||||
};
|
||||
LayeredMap.new = func(parent, name)
|
||||
return make(LayeredMap, parent.createChild("map",name) );
|
||||
|
||||
LayeredMap.listen = func(p,c) { #FIXME: listening should be managed by each m/v/c separately
|
||||
# print("Setting up LayeredMap-managed listener:", p);
|
||||
append(me.listeners, setlistener(p, c));
|
||||
}
|
||||
|
||||
LayeredMap.initializeLayers = func {
|
||||
# print("initializing all layers and updating");
|
||||
foreach(var l; me.layers)
|
||||
l.update();
|
||||
}
|
||||
|
||||
LayeredMap.setRefPos = func(lat, lon) {
|
||||
# print("RefPos set");
|
||||
me._node.getNode("ref-lat", 1).setDoubleValue(lat);
|
||||
me._node.getNode("ref-lon", 1).setDoubleValue(lon);
|
||||
me; # chainable
|
||||
}
|
||||
LayeredMap.setHdg = func(hdg) {
|
||||
me._node.getNode("hdg",1).setDoubleValue(hdg);
|
||||
me; # chainable
|
||||
}
|
||||
|
||||
LayeredMap.updateZoom = func {
|
||||
var z = getprop(me.zoom_property) or 0;
|
||||
var zoom = me.ranges[ size(me.ranges)-1 -z];
|
||||
# print("Setting zoom range to:", zoom);
|
||||
benchmark("Zooming map:"~zoom, func
|
||||
me._node.getNode("range", 1).setDoubleValue(zoom)
|
||||
);
|
||||
me; #chainable
|
||||
}
|
||||
|
||||
# this is a huge hack at the moment, we need to encapsulate the setRefPos/setHdg methods, so that they are exposed to XML space
|
||||
#
|
||||
LayeredMap.updateState = func {
|
||||
# center map on airport TODO: should be moved to a method and wrapped with a controller so that behavior can be customizeda
|
||||
#var apt = me.layers[0]._model._elements[0];
|
||||
# FIXME:
|
||||
#me.setRefPos(lat:me._refpos.lat, lon:me._refpos.lon);
|
||||
|
||||
me.setHdg(0.0);
|
||||
me.updateZoom();
|
||||
}
|
||||
|
||||
#
|
||||
# TODO: this is currently GUI specific and not re-usable for instruments
|
||||
LayeredMap.setupZoom = func(dialog) {
|
||||
var dlgroot = dialog.getNode("features/dialog-root").getValue();#FIXME: GUI specific - needs to be re-implemented for instruments
|
||||
var zoom_property = dlgroot ~"/"~dialog.getNode("features/range-property").getValue(); #FIXME: this doesn't belong here, need to be in ctor instead !!!
|
||||
ranges=dialog.getNode("features/ranges").getChildren("range");
|
||||
foreach(var r; ranges)
|
||||
append(me.ranges, r.getValue() );
|
||||
|
||||
# print("Setting up Zoom Ranges:", size(ranges)-1);
|
||||
me.zoom_property=zoom_property;
|
||||
me.listen(zoom_property, func me.updateZoom() );
|
||||
me.updateZoom();
|
||||
me; #chainable
|
||||
}
|
||||
LayeredMap.setZoom = func {} #TODO
|
||||
|
||||
LayeredMap.resetLayers = func {
|
||||
|
||||
benchmark("Resetting LayeredMap", func
|
||||
foreach(var l; me.layers) { #TODO: hide all layers, hide map
|
||||
l.reset();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#FIXME: listener management should be done at the MVC level, for each component - not as part of the LayeredMap!
|
||||
LayeredMap.cleanup_listeners = func {
|
||||
print("Cleaning up listeners");
|
||||
foreach(var l; me.listeners)
|
||||
removelistener(l);
|
||||
|
||||
}
|
||||
|
||||
###
|
||||
# GenericMap: A generic map is a layered map that puts all supported features on a different layer (canvas group) so that
|
||||
# they can be individually toggled on/off so that unnecessary updates are avoided, there are methods to link layers to boolean properties
|
||||
# so that they can be easily associated with GUI properties (checkboxes) or cockpit hotspots
|
||||
# TODO: generalize the XML-parametrization and move it to a helper class
|
||||
|
||||
var GenericMap = { };
|
||||
GenericMap.new = func(parent, name) make(LayeredMap.new(parent:parent, name:name), GenericMap);
|
||||
|
||||
GenericMap.setupLayer = func(layer, property) {
|
||||
var l = MAP_LAYERS[layer].new(me, layer); # Layer.new(me, layer);
|
||||
l.display_layer = property; #FIXME: use controller object instead here and this overlaps with update_property
|
||||
#print("Set up layer with toggle property=", property);
|
||||
l._view.setVisible( getprop(property) ) ;
|
||||
append(me.layers, l);
|
||||
return l;
|
||||
}
|
||||
|
||||
# features are layers - so this will do layer setup and then register listeners for each layer
|
||||
GenericMap.setupFeature = func(layer, property, init ) {
|
||||
var l=me.setupLayer( layer, property );
|
||||
me.listen(property, func l.toggle() ); #TODO: should use the controller object here !
|
||||
|
||||
l._model._update_property=property; #TODO: move somewhere else - this is the property that is mapped to the CHECKBOX
|
||||
l._model._view_handle = l; #FIXME: very crude, set a handle to the view(group), so that the model can notify it (for updates)
|
||||
l._model._map_handle = me; #FIXME: added here so that layers can send update requests to the parent map
|
||||
#print("Setting up layer init for property:", init);
|
||||
|
||||
l._model._input_property = init; # FIXME: init property = input property - needs to be improved!
|
||||
me.listen(init, func l._model.init() ); #TODO: makes sure that the layer's init method for the MODEL is invoked
|
||||
me; #chainable
|
||||
};
|
||||
|
||||
# This will read in the config and procedurally instantiate all requested layers and link them to toggle properties
|
||||
# FIXME: this is currently GUI specific and doesn't yet support instrument use, i.e. needs to be generalized further
|
||||
GenericMap.pickupFeatures = func(DIALOG_CANVAS) {
|
||||
var dlgroot = DIALOG_CANVAS.getNode("features/dialog-root").getValue();
|
||||
# print("Picking up features for:", DIALOG_CANVAS.getPath() );
|
||||
var layers=DIALOG_CANVAS.getNode("features").getChildren("layer");
|
||||
foreach(var n; layers) {
|
||||
var name = n.getNode("name").getValue();
|
||||
var toggle = n.getNode("property").getValue();
|
||||
var init = n.getNode("init-property").getValue();
|
||||
init = dlgroot ~"/"~init;
|
||||
var property = dlgroot ~"/"~toggle;
|
||||
# print("Adding layer:",n.getNode("name").getValue() );
|
||||
me.setupFeature(name, property, init);
|
||||
}
|
||||
me;
|
||||
}
|
||||
|
||||
# NOT a method, cmdarg() is no longer meaningful when the canvas nasal block is executed
|
||||
# so this needs to be called in the dialog's OPEN block instead - TODO: generalize
|
||||
#FIXME: move somewhere else, this is a GUI helper and should probably be generalized and moved to gui.nas
|
||||
GenericMap.setupGUI = func (dialog, group) {
|
||||
var group = gui.findElementByName(cmdarg() , group);
|
||||
|
||||
var layers=dialog.getNode("features").getChildren("layer");
|
||||
var template = dialog.getNode("checkbox-toggle-template");
|
||||
var dlgroot = dialog.getNode("features/dialog-root").getValue();
|
||||
var zoom = dlgroot ~"/"~ dialog.getNode("features/range-property").getValue();
|
||||
var i=0;
|
||||
foreach(var n; layers) {
|
||||
var name = n.getNode("name").getValue();
|
||||
var toggle = dlgroot ~ "/" ~ n.getNode("property").getValue();
|
||||
var label = n.getNode("description",1).getValue() or name;
|
||||
|
||||
var default = n.getNode("default",1).getValue();
|
||||
default = (default=="enabled")?1:0;
|
||||
#print("Layer default for", name ," is:", default);
|
||||
setprop(toggle, default); # set the checkbox to its default setting
|
||||
|
||||
var hide_checkbox = n.getNode("hide-checkbox",1).getValue();
|
||||
hide_checkbox = (hide_checkbox=="true")?1:0;
|
||||
|
||||
var checkbox = group.getChild("checkbox",i, 1); #FIXME: compute proper offset dynamically, will currently overwrite other existing checkboxes!
|
||||
|
||||
props.copy(template, checkbox);
|
||||
checkbox.getNode("name").setValue("display-"~name);
|
||||
checkbox.getNode("label").setValue(label);
|
||||
checkbox.getNode("property").setValue(toggle);
|
||||
checkbox.getNode("binding/object-name").setValue("display-"~name);
|
||||
checkbox.getNode("enabled",1).setValue(!hide_checkbox);
|
||||
i+=1;
|
||||
}
|
||||
|
||||
#add zoom buttons procedurally:
|
||||
var template = dialog.getNode("zoom-template");
|
||||
template.getNode("button[0]/binding[0]/property[0]").setValue(zoom);
|
||||
template.getNode("text[0]/property[0]").setValue(zoom);
|
||||
template.getNode("button[1]/binding[0]/property[0]").setValue(zoom);
|
||||
template.getNode("button[1]/binding[0]/max[0]").setValue( i );
|
||||
props.copy(template, group);
|
||||
}
|
||||
|
||||
###
|
||||
# TODO: StylableGenericMap (colors, fonts, symbols)
|
||||
#
|
||||
|
||||
var AirportMap = {};
|
||||
AirportMap.new = func(parent,name) make(GenericMap.new(parent,name), AirportMap);
|
||||
#TODO: Use real MVC (DataProvider/PositionedProvider) here
|
||||
|
||||
|
||||
# this is currently "directly" invoked via a listener, needs to be changed
|
||||
# to use the controller object instead
|
||||
# TODO: adopt real MVC here
|
||||
# FIXME: this must currently be explicitly called by the model, we need to use a wrapper to call it automatically instead!
|
||||
LayerModel.notifyView = func () {
|
||||
# print("View notified");
|
||||
me._view_handle.update(); # update the layer/group
|
||||
me._map_handle.updateState(); # update the map
|
||||
}
|
||||
|
||||
# ID
|
||||
var SingleAirportProvider = {};
|
||||
|
||||
# inputs: position, range
|
||||
var MultiAirportProvider = {};
|
||||
|
||||
#TODO: remove and unify with update()
|
||||
AirportMap.init = func {
|
||||
me.resetLayers();
|
||||
me.updateState();
|
||||
}
|
||||
|
||||
# MultiObjectLayer:
|
||||
# - Airports
|
||||
# - Traffic (MP/AI)
|
||||
# - Navaids
|
||||
#
|
||||
|
||||
# TODO: a "MapLayer" is a full MVC implementation that is owned by a "LayeredMap"
|
||||
|
||||
var MAP_LAYERS = {};
|
||||
var register_layer = func(name, layer) MAP_LAYERS[name]=layer;
|
||||
|
||||
var MVC_FOLDER = getprop("/sim/fg-root") ~ "/Nasal/canvas/map/";
|
||||
var load_modules = func(vec) foreach(var file; vec) io.load_nasal(MVC_FOLDER~file, "canvas");
|
||||
|
||||
# TODO: read in the file names dynamically: *.draw, *.model, *.layer
|
||||
|
||||
var DRAWABLES = ["navaid.draw", "parking.draw", "runways.draw", "taxiways.draw", "tower.draw"];
|
||||
load_modules(DRAWABLES);
|
||||
|
||||
var MODELS = ["airports.model", "navaids.model",];
|
||||
load_modules(MODELS);
|
||||
|
||||
var LAYERS = ["runways.layer", "taxiways.layer", "parking.layer", "tower.layer", "navaids.layer","test.layer",];
|
||||
load_modules(LAYERS);
|
||||
|
||||
#TODO: Implement!
|
||||
var CONTROLLERS = [];
|
||||
load_modules(CONTROLLERS);
|
||||
|
|
0
Nasal/canvas/map/README.txt
Normal file
0
Nasal/canvas/map/README.txt
Normal file
27
Nasal/canvas/map/airports.model
Normal file
27
Nasal/canvas/map/airports.model
Normal file
|
@ -0,0 +1,27 @@
|
|||
var AirportModel = {};
|
||||
AirportModel.new = func make(AirportModel, LayerModel);
|
||||
|
||||
# FIXME: Just testing for now: This really shouldn't be part of the core LayerModel, needs to go to "AirportModel" instead
|
||||
# FIXME: This will get called ONCE for EACH layer that uses the AirportModel, so VERY inefficient ATM! => should be shared among layers
|
||||
AirportModel.init = func {
|
||||
# print("AirportModel initialized!");
|
||||
# me._map_handle.resetLayers();
|
||||
me._view_handle.reset();
|
||||
var id = getprop(me._input_property); # HACK: this needs to be handled via the controller - introduce "input_property"
|
||||
#print("ID is:", id);
|
||||
(id == "") and return;
|
||||
var apt=airportinfo(id); # FIXME: replace with controller call to update the model
|
||||
#var airports = findAirportsWithinRange(apt.lat, apt.lon, 10); # HACK: expose the range !!
|
||||
foreach(var a; [ apt ]) #FIXME: move to separate method: "populate"
|
||||
# print("storing:", a.id) and
|
||||
me.push(a);
|
||||
#print("Work items in Model:", me.hasData() );
|
||||
#print("Model updated!!");
|
||||
|
||||
# set RefPos and hdg to apt !!
|
||||
me._map_handle.setRefPos(apt.lat, apt.lon);
|
||||
|
||||
#TODO: Notify view on update - use proper NOTIFICATIONS (INIT; UPDATE etc)
|
||||
me.notifyView();
|
||||
}
|
||||
|
0
Nasal/canvas/map/fixes.model
Normal file
0
Nasal/canvas/map/fixes.model
Normal file
15
Nasal/canvas/map/navaid.draw
Normal file
15
Nasal/canvas/map/navaid.draw
Normal file
|
@ -0,0 +1,15 @@
|
|||
##
|
||||
# FIXME: until we have better instancing support for symbols, it would be better to return a functor here
|
||||
# so that symbols are only parsed once
|
||||
var NAVAID_CACHE = {};
|
||||
var draw_navaid = func (group, navaid, lod) {
|
||||
#var group = group.createChild("group", "navaid");
|
||||
DEBUG and print("Drawing navaid:", navaid.id);
|
||||
var symbols = {NDB:"/gui/dialogs/images/ndb_symbol.svg"}; # TODO: add more navaid symbols here
|
||||
if (symbols[navaid.type] == nil) return print("Missing svg image for navaid:", navaid.type);
|
||||
|
||||
var symbol_navaid = group.createChild("group", "navaid");
|
||||
canvas.parsesvg(symbol_navaid, symbols[navaid.type]);
|
||||
symbol_navaid.setGeoPosition(navaid.lat, navaid.lon);
|
||||
}
|
||||
|
9
Nasal/canvas/map/navaids.layer
Normal file
9
Nasal/canvas/map/navaids.layer
Normal file
|
@ -0,0 +1,9 @@
|
|||
var NavLayer = {};
|
||||
NavLayer.new = func(group,name) {
|
||||
var m=Layer.new(group, name, NavaidModel);
|
||||
m.setDraw (func draw_layer(layer:m, callback: draw_navaid, lod:0) );
|
||||
return m;
|
||||
}
|
||||
|
||||
register_layer("navaids", NavLayer);
|
||||
|
11
Nasal/canvas/map/navaids.model
Normal file
11
Nasal/canvas/map/navaids.model
Normal file
|
@ -0,0 +1,11 @@
|
|||
var NavaidModel = {};
|
||||
NavaidModel.new = func make(LayerModel, NavaidModel);
|
||||
NavaidModel.init = func {
|
||||
me._view_handle.reset();
|
||||
var navaids = findNavaidsWithinRange(15);
|
||||
foreach(var n; navaids)
|
||||
me.push(n);
|
||||
me.notifyView();
|
||||
}
|
||||
|
||||
|
15
Nasal/canvas/map/parking.draw
Normal file
15
Nasal/canvas/map/parking.draw
Normal file
|
@ -0,0 +1,15 @@
|
|||
var draw_parking = func(group, apt, lod) {
|
||||
var group = group.createChild("group", "apt-"~apt.id);
|
||||
foreach(var park; apt.parking())
|
||||
{
|
||||
var icon_park =
|
||||
group.createChild("text", "parking-" ~ park.name)
|
||||
.setDrawMode( canvas.Text.ALIGNMENT
|
||||
+ canvas.Text.TEXT )
|
||||
.setText(park.name)
|
||||
.setFont("LiberationFonts/LiberationMono-Bold.ttf")
|
||||
.setGeoPosition(park.lat, park.lon)
|
||||
.setFontSize(15, 1.3);
|
||||
}
|
||||
}
|
||||
|
9
Nasal/canvas/map/parking.layer
Normal file
9
Nasal/canvas/map/parking.layer
Normal file
|
@ -0,0 +1,9 @@
|
|||
#TODO: use custom Model/DataProvider
|
||||
var ParkingLayer = {}; # make(Layer);
|
||||
ParkingLayer.new = func(group, name) {
|
||||
var m=Layer.new(group, name, AirportModel ); #FIXME: AirportModel can be shared by Taxiways, Runways etc!!
|
||||
m.setDraw( func draw_layer(layer: m, callback: draw_parking, lod:0 ) );
|
||||
return m;
|
||||
}
|
||||
|
||||
register_layer("parkings", ParkingLayer);
|
113
Nasal/canvas/map/runways.draw
Normal file
113
Nasal/canvas/map/runways.draw
Normal file
|
@ -0,0 +1,113 @@
|
|||
|
||||
#TODO: split: draw_single_runway(pos)
|
||||
var draw_runways = func(group, apt,lod) {
|
||||
DEBUG and print("Drawing runways for:", apt.id);
|
||||
# var group = group.createChild("group", "apt-"~apt.id);
|
||||
# group = group.createChild("group", "runways");
|
||||
var rws_done = {};
|
||||
foreach(var rw; keys(apt.runways))
|
||||
{
|
||||
var is_heli = substr(rw, 0, 1) == "H";
|
||||
var rw_dir = is_heli ? nil : int(substr(rw, 0, 2));
|
||||
|
||||
var rw_rec = "";
|
||||
var thresh_rec = 0;
|
||||
if( rw_dir != nil )
|
||||
{
|
||||
rw_rec = sprintf("%02d", math.mod(rw_dir - 18, 36));
|
||||
if( size(rw) == 3 )
|
||||
{
|
||||
var map_rec = {
|
||||
"R": "L",
|
||||
"L": "R",
|
||||
"C": "C"
|
||||
};
|
||||
rw_rec ~= map_rec[substr(rw, 2)];
|
||||
}
|
||||
|
||||
if( rws_done[rw_rec] != nil )
|
||||
continue;
|
||||
|
||||
var rw_rec = apt.runways[rw_rec];
|
||||
if( rw_rec != nil )
|
||||
thresh_rec = rw_rec.threshold;
|
||||
}
|
||||
|
||||
rws_done[rw] = 1;
|
||||
|
||||
rw = apt.runways[rw];
|
||||
|
||||
var clr = SURFACECOLORS[rw.surface];
|
||||
if (clr == nil) { clr = SURFACECOLORS[0]};
|
||||
|
||||
var icon_rw =
|
||||
group.createChild("path", "runway-" ~ rw.id)
|
||||
.setStrokeLineWidth(0.5)
|
||||
.setColor(1.0,1.0,1.0)
|
||||
.setColorFill(clr.r, clr.g, clr.b);
|
||||
|
||||
var rwy = Runway.new(rw);
|
||||
var beg_thr = rwy.pointOffCenterline(rw.threshold);
|
||||
var beg_thr1 = rwy.pointOffCenterline(rw.threshold, 0.5 * rw.width);
|
||||
var beg_thr2 = rwy.pointOffCenterline(rw.threshold, -0.5 * rw.width);
|
||||
var beg1 = rwy.pointOffCenterline(0, 0.5 * rw.width);
|
||||
var beg2 = rwy.pointOffCenterline(0, -0.5 * rw.width);
|
||||
|
||||
var end_thr = rwy.pointOffCenterline(rw.length - thresh_rec);
|
||||
var end_thr1 = rwy.pointOffCenterline(rw.length - thresh_rec, 0.5 * rw.width);
|
||||
var end_thr2 = rwy.pointOffCenterline(rw.length - thresh_rec, -0.5 * rw.width);
|
||||
var end1 = rwy.pointOffCenterline(rw.length, 0.5 * rw.width);
|
||||
var end2 = rwy.pointOffCenterline(rw.length, -0.5 * rw.width);
|
||||
|
||||
icon_rw.setDataGeo
|
||||
(
|
||||
[ canvas.Path.VG_MOVE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_CLOSE_PATH ],
|
||||
[ beg1[0], beg1[1],
|
||||
beg2[0], beg2[1],
|
||||
end2[0], end2[1],
|
||||
end1[0], end1[1] ]
|
||||
);
|
||||
|
||||
if( rw.length / rw.width > 3 and !is_heli )
|
||||
{
|
||||
# only runways which are much longer than wide are
|
||||
# real runways, otherwise it's probably a heliport.
|
||||
var icon_cl =
|
||||
group.createChild("path", "centerline")
|
||||
.setStrokeLineWidth(0.5)
|
||||
.setColor(1,1,1)
|
||||
.setStrokeDashArray([15, 10]);
|
||||
|
||||
icon_cl.setDataGeo
|
||||
(
|
||||
[ canvas.Path.VG_MOVE_TO,
|
||||
canvas.Path.VG_LINE_TO ],
|
||||
[ beg_thr[0], beg_thr[1],
|
||||
end_thr[0], end_thr[1] ]
|
||||
);
|
||||
|
||||
var icon_thr =
|
||||
group.createChild("path", "threshold")
|
||||
.setStrokeLineWidth(1.5)
|
||||
.setColor(1,1,1);
|
||||
|
||||
icon_thr.setDataGeo
|
||||
(
|
||||
[ canvas.Path.VG_MOVE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_MOVE_TO,
|
||||
canvas.Path.VG_LINE_TO ],
|
||||
[ beg_thr1[0], beg_thr1[1],
|
||||
beg_thr2[0], beg_thr2[1],
|
||||
end_thr1[0], end_thr1[1],
|
||||
end_thr2[0], end_thr2[1] ]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
10
Nasal/canvas/map/runways.layer
Normal file
10
Nasal/canvas/map/runways.layer
Normal file
|
@ -0,0 +1,10 @@
|
|||
#TODO: use custom Model/DataProvider
|
||||
var RunwayLayer = {}; # make(Layer);
|
||||
RunwayLayer.new = func(group, name) {
|
||||
# print("Setting up new TestLayer");
|
||||
var m=Layer.new(group, name, AirportModel ); #FIXME: AirportModel can be shared by Taxiways, Runways etc!!
|
||||
m.setDraw( func draw_layer(layer: m, callback: draw_runways, lod:0 ) );
|
||||
return m;
|
||||
}
|
||||
register_layer("runways", RunwayLayer);
|
||||
|
40
Nasal/canvas/map/taxiways.draw
Normal file
40
Nasal/canvas/map/taxiways.draw
Normal file
|
@ -0,0 +1,40 @@
|
|||
var draw_taxiways = func(group, apt, lod) { # TODO: the LOD arg isn't stricly needed here,
|
||||
# the layer is a conventional canvas group, so it can access its map
|
||||
# parent and just read the "range" property to do LOD handling
|
||||
group.set("z-index",-100); # HACK: we need to encapsulate this
|
||||
# var group = group.createChild("group", "apt-"~apt.id); #FIXME: we don't need to use two nested groups for each taxiway - performance?
|
||||
# group = group.createChild("group", "taxiways");
|
||||
# print("drawing taxiways for:", apt.id);
|
||||
# Taxiways drawn first so the runways and parking positions end up on top.
|
||||
foreach(var taxi; apt.taxiways)
|
||||
{
|
||||
var clr = SURFACECOLORS[taxi.surface];
|
||||
if (clr == nil) { clr = SURFACECOLORS[0]};
|
||||
|
||||
var icon_taxi =
|
||||
group.createChild("path", "taxi")
|
||||
.setStrokeLineWidth(0)
|
||||
.setColor(clr.r, clr.g, clr.b)
|
||||
.setColorFill(clr.r, clr.g, clr.b);
|
||||
|
||||
var txi = Runway.new(taxi);
|
||||
var beg1 = txi.pointOffCenterline(0, 0.5 * taxi.width);
|
||||
var beg2 = txi.pointOffCenterline(0, -0.5 * taxi.width);
|
||||
var end1 = txi.pointOffCenterline(taxi.length, 0.5 * taxi.width);
|
||||
var end2 = txi.pointOffCenterline(taxi.length, -0.5 * taxi.width);
|
||||
|
||||
icon_taxi.setDataGeo
|
||||
(
|
||||
[ canvas.Path.VG_MOVE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_LINE_TO,
|
||||
canvas.Path.VG_CLOSE_PATH ],
|
||||
[ beg1[0], beg1[1],
|
||||
beg2[0], beg2[1],
|
||||
end2[0], end2[1],
|
||||
end1[0], end1[1] ]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
11
Nasal/canvas/map/taxiways.layer
Normal file
11
Nasal/canvas/map/taxiways.layer
Normal file
|
@ -0,0 +1,11 @@
|
|||
#TODO: use custom Model/DataProvider
|
||||
var TaxiwayLayer = {}; # make(Layer);
|
||||
TaxiwayLayer.new = func(group, name) {
|
||||
# print("Setting up new TestLayer");
|
||||
var m=Layer.new(group, name, AirportModel ); #FIXME: AirportModel can be shared by Taxiways, Runways etc!!
|
||||
m.setDraw( func draw_layer(layer: m, callback: draw_taxiways, lod:0 ) );
|
||||
return m;
|
||||
}
|
||||
|
||||
register_layer("taxiways", TaxiwayLayer);
|
||||
|
11
Nasal/canvas/map/test.layer
Normal file
11
Nasal/canvas/map/test.layer
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
#TODO: use custom Model/DataProvider
|
||||
var TestLayer = {}; # make(Layer);
|
||||
TestLayer.new = func(group, name) {
|
||||
# print("Setting up new TestLayer");
|
||||
var m=Layer.new(group, name, AirportModel ); #FIXME: AirportModel can be shared by Taxiways, Runways etc!!
|
||||
m.setDraw( func draw_layer(layer: m, callback: MAP_LAYERS["runways"], lod:0 ) );
|
||||
return m;
|
||||
}
|
||||
|
||||
register_layer("airport_test", TestLayer);
|
19
Nasal/canvas/map/tower.draw
Normal file
19
Nasal/canvas/map/tower.draw
Normal file
|
@ -0,0 +1,19 @@
|
|||
var draw_tower = func (group, apt,lod) {
|
||||
var group = group.createChild("group", "tower");
|
||||
# TODO: move to map_elements.nas (tower, runway, parking etc)
|
||||
# i.e.: set_element(group, "tower", "style");
|
||||
var icon_tower =
|
||||
group.createChild("path", "tower")
|
||||
.setStrokeLineWidth(1)
|
||||
.setScale(1.5)
|
||||
.setColor(0.2,0.2,1.0)
|
||||
.moveTo(-3, 0)
|
||||
.vert(-10)
|
||||
.line(-3, -10)
|
||||
.horiz(12)
|
||||
.line(-3, 10)
|
||||
.vert(10);
|
||||
|
||||
icon_tower.setGeoPosition(apt.lat, apt.lon);
|
||||
}
|
||||
|
8
Nasal/canvas/map/tower.layer
Normal file
8
Nasal/canvas/map/tower.layer
Normal file
|
@ -0,0 +1,8 @@
|
|||
var TowerLayer = {};
|
||||
TowerLayer.new = func(group, name) {
|
||||
var m=Layer.new(group, name, AirportModel ); #FIXME: AirportModel can be shared by Taxiways, Runways etc!!
|
||||
m.setDraw( func draw_layer(layer: m, callback: draw_tower, lod:0 ) );
|
||||
return m;
|
||||
}
|
||||
register_layer("towers", TowerLayer);
|
||||
|
0
Nasal/canvas/map/waypoints.model
Normal file
0
Nasal/canvas/map/waypoints.model
Normal file
|
@ -159,6 +159,7 @@ _setlistener("/sim/signals/nasal-dir-initialized", func {
|
|||
menuEnable("rendering-buffers", getprop("/sim/rendering/rembrandt/enabled"));
|
||||
menuEnable("rembrandt-buffers-choice", getprop("/sim/rendering/rembrandt/enabled"));
|
||||
menuEnable("stereoscopic-options", !getprop("/sim/rendering/rembrandt/enabled"));
|
||||
menuEnable("sound-config", getprop("/sim/sound/working"));
|
||||
|
||||
# frame-per-second display
|
||||
var fps = props.globals.getNode("/sim/rendering/fps-display", 1);
|
||||
|
|
|
@ -611,7 +611,7 @@ var readConfig = func(dialog_root="/sim/gui/dialogs/joystick-config") {
|
|||
|
||||
if (a != nil) {
|
||||
# Read properties from bindings
|
||||
props.copy(a, p.getNode("original_binding", 1));
|
||||
props.copy(a, btn.getNode("original_binding", 1));
|
||||
var binding = nil;
|
||||
foreach (var b; joystick.buttonBindings) {
|
||||
if ((binding == nil) and (a != nil) and b.match(a)) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
var index = nil; # current view index
|
||||
var views = nil; # list of all view branches (/sim/view[n]) as props.Node
|
||||
var current = nil; # current view branch (e.g. /sim/view[1]) as props.Node
|
||||
|
||||
var fovProp = nil;
|
||||
|
||||
var hasmember = func(class, member) {
|
||||
if (contains(class, member))
|
||||
|
@ -235,6 +235,7 @@ var manager = {
|
|||
me.current.handler.start();
|
||||
if (hasmember(me.current.handler, "update"))
|
||||
me._loop_(me.loopid += 1);
|
||||
resetFOV();
|
||||
},
|
||||
reset : func {
|
||||
if (hasmember(me.current.handler, "reset"))
|
||||
|
@ -638,7 +639,61 @@ var point = {
|
|||
|
||||
|
||||
|
||||
var fovProp = nil;
|
||||
##
|
||||
# view.ScreenWidthCompens: optional FOV compensation for wider screens.
|
||||
# It keeps an equivalent of 55° FOV on a 4:3 zone centered on the screen
|
||||
# whichever is the screen width/height ratio. Works only if width >= height.
|
||||
#
|
||||
# status: 0=Init, 1=toggle option, 2=waiting for the window size to change.
|
||||
|
||||
var defaultFov = nil;
|
||||
var oldW = 0;
|
||||
var oldH = 0;
|
||||
var fovStore = {};
|
||||
|
||||
var screenWidthCompens = func(status) {
|
||||
var opt = getprop("/sim/current-view/field-of-view-compensation");
|
||||
if (status == 0) {
|
||||
defaultFov = getprop("/sim/current-view/config/default-field-of-view-deg");
|
||||
forindex (var i; views) {
|
||||
var defaultFovNode = views[i].getNode("config/default-field-of-view-deg", 1);
|
||||
fovStore[i] = defaultFovNode.getValue();
|
||||
}
|
||||
} elsif (status == 1) {
|
||||
opt = ! opt;
|
||||
setprop("/sim/current-view/field-of-view-compensation", opt);
|
||||
if (! opt) {
|
||||
forindex (var i; views) {
|
||||
var defaultFovNode = views[i].getNode("config/default-field-of-view-deg", 1);
|
||||
defaultFovNode.setValue(fovStore[i]);
|
||||
}
|
||||
var vn = getprop("/sim/current-view/view-number");
|
||||
setprop("/sim/current-view/field-of-view", fovStore[vn]);
|
||||
}
|
||||
} elsif (status == 2 and ! opt) {
|
||||
return;
|
||||
}
|
||||
var w = getprop("/sim/rendering/camera-group/camera/viewport/width");
|
||||
var h = getprop("/sim/rendering/camera-group/camera/viewport/height");
|
||||
if (! opt) {
|
||||
setprop("/sim/current-view/config/default-field-of-view-deg", defaultFov);
|
||||
return;
|
||||
}
|
||||
if ( w != oldW or h != oldH or status == 1) {
|
||||
oldW = w;
|
||||
oldH = h;
|
||||
d = 1.28066 * h; # 1.28066 = 4/3 (width/height ratio) / 2 / tan(55°)
|
||||
newFov = 2 * math.atan2( w / h * h / 2, d) * R2D;
|
||||
setprop("/sim/current-view/config/default-field-of-view-deg", newFov);
|
||||
forindex (var i; views) {
|
||||
var defaultFovNode = views[i].getNode("config/default-field-of-view-deg", 1);
|
||||
defaultFovNode.setValue(newFov);
|
||||
}
|
||||
fovProp.setValue(newFov);
|
||||
}
|
||||
settimer(func { screenWidthCompens(2); }, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_setlistener("/sim/signals/nasal-dir-initialized", func {
|
||||
|
@ -654,6 +709,7 @@ _setlistener("/sim/signals/nasal-dir-initialized", func {
|
|||
manager.init();
|
||||
manager.register("Fly-By View", fly_by_view_handler);
|
||||
manager.register("Model View", model_view_handler);
|
||||
screenWidthCompens(0);
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ void main (void)
|
|||
|
||||
|
||||
//adding snow and permanent snow/glacier
|
||||
if (vegetationlevel > snowlevel || vegetationlevel > 3100.0) {
|
||||
if (vegetationlevel > snowlevel) {
|
||||
c3 = mix(vec4(n+1.0, n+1.0, n+1.0, 0.0), c1, smoothstep(0.990, 0.965, abs(normalize(Normal).z)+nvL[2]*1.3));
|
||||
c4 = mix(vec4(n+1.0, n+1.0, n+1.0, 0.0), c1, smoothstep(0.990, 0.965, abs(normalize(Normal).z)+nvL[2]*0.9));
|
||||
c5 = mix(c3, c4, 1.0);
|
||||
|
|
|
@ -30,6 +30,7 @@ uniform float overcast;
|
|||
uniform float eye_alt;
|
||||
uniform float snowlevel;
|
||||
uniform float dust_cover_factor;
|
||||
uniform float lichen_cover_factor;
|
||||
uniform float wetness;
|
||||
uniform float fogstructure;
|
||||
uniform int quality_level;
|
||||
|
@ -51,53 +52,53 @@ float cosine_interpolate(in float a, in float b, in float x)
|
|||
{
|
||||
float ft = x * 3.1415927;
|
||||
float f = (1.0 - cos(ft)) * .5;
|
||||
|
||||
|
||||
return a*(1.0-f) + b*f;
|
||||
}
|
||||
|
||||
float simple_interpolate(in float a, in float b, in float x)
|
||||
{
|
||||
return a + smoothstep(0.0,1.0,x) * (b-a);
|
||||
//return mix(a,b,x);
|
||||
return a + smoothstep(0.0,1.0,x) * (b-a);
|
||||
//return mix(a,b,x);
|
||||
}
|
||||
|
||||
float interpolatedNoise2D(in float x, in float y)
|
||||
{
|
||||
float integer_x = x - fract(x);
|
||||
float fractional_x = x - integer_x;
|
||||
|
||||
float integer_y = y - fract(y);
|
||||
float fractional_y = y - integer_y;
|
||||
|
||||
float v1 = rand2D(vec2(integer_x, integer_y));
|
||||
float v2 = rand2D(vec2(integer_x+1.0, integer_y));
|
||||
float v3 = rand2D(vec2(integer_x, integer_y+1.0));
|
||||
float v4 = rand2D(vec2(integer_x+1.0, integer_y +1.0));
|
||||
|
||||
float i1 = simple_interpolate(v1 , v2 , fractional_x);
|
||||
float i2 = simple_interpolate(v3 , v4 , fractional_x);
|
||||
|
||||
return simple_interpolate(i1 , i2 , fractional_y);
|
||||
float integer_x = x - fract(x);
|
||||
float fractional_x = x - integer_x;
|
||||
|
||||
float integer_y = y - fract(y);
|
||||
float fractional_y = y - integer_y;
|
||||
|
||||
float v1 = rand2D(vec2(integer_x, integer_y));
|
||||
float v2 = rand2D(vec2(integer_x+1.0, integer_y));
|
||||
float v3 = rand2D(vec2(integer_x, integer_y+1.0));
|
||||
float v4 = rand2D(vec2(integer_x+1.0, integer_y +1.0));
|
||||
|
||||
float i1 = simple_interpolate(v1 , v2 , fractional_x);
|
||||
float i2 = simple_interpolate(v3 , v4 , fractional_x);
|
||||
|
||||
return simple_interpolate(i1 , i2 , fractional_y);
|
||||
}
|
||||
|
||||
|
||||
float Noise2D(in vec2 coord, in float wavelength)
|
||||
{
|
||||
return interpolatedNoise2D(coord.x/wavelength, coord.y/wavelength);
|
||||
|
||||
return interpolatedNoise2D(coord.x/wavelength, coord.y/wavelength);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
|
||||
{
|
||||
x = x - 0.5;
|
||||
|
||||
// use the asymptotics to shorten computations
|
||||
if (x > 30.0) {return e;}
|
||||
if (x < -15.0) {return 0.0;}
|
||||
|
||||
return e / pow((1.0 + a * exp(-b * (x-c)) ),(1.0/d));
|
||||
x = x - 0.5;
|
||||
|
||||
// use the asymptotics to shorten computations
|
||||
if (x > 30.0) {return e;}
|
||||
if (x < -15.0) {return 0.0;}
|
||||
|
||||
return e / pow((1.0 + a * exp(-b * (x-c)) ),(1.0/d));
|
||||
}
|
||||
|
||||
// this determines how light is attenuated in the distance
|
||||
|
@ -106,32 +107,39 @@ float light_func (in float x, in float a, in float b, in float c, in float d, in
|
|||
|
||||
float fog_func (in float targ)
|
||||
{
|
||||
float fade_mix;
|
||||
|
||||
// for large altitude > 30 km, we switch to some component of quadratic distance fading to
|
||||
// create the illusion of improved visibility range
|
||||
|
||||
targ = 1.25 * targ * smoothstep(0.04,0.06,targ); // need to sync with the distance to which terrain is drawn
|
||||
|
||||
|
||||
if (alt < 30000.0) {
|
||||
return exp(-targ - targ * targ * targ * targ);
|
||||
|
||||
|
||||
float fade_mix;
|
||||
|
||||
// for large altitude > 30 km, we switch to some component of quadratic distance fading to
|
||||
// create the illusion of improved visibility range
|
||||
|
||||
targ = 1.25 * targ * smoothstep(0.04,0.06,targ); // need to sync with the distance to which terrain is drawn
|
||||
|
||||
|
||||
if (alt < 30000.0)
|
||||
{return exp(-targ - targ * targ * targ * targ);}
|
||||
else if (alt < 50000.0)
|
||||
{
|
||||
fade_mix = (alt - 30000.0)/20000.0;
|
||||
return fade_mix * exp(-targ*targ - pow(targ,4.0)) + (1.0 - fade_mix) * exp(-targ - pow(targ,4.0));
|
||||
}
|
||||
else if (alt < 50000.0) {
|
||||
fade_mix = (alt - 30000.0)/20000.0;
|
||||
return fade_mix * exp(-targ*targ - pow(targ,4.0)) + (1.0 - fade_mix) * exp(-targ - pow(targ,4.0));
|
||||
else
|
||||
{
|
||||
return exp(- targ * targ - pow(targ,4.0));
|
||||
}
|
||||
else {
|
||||
return exp(- targ * targ - pow(targ,4.0));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float dist = length(relPos);
|
||||
|
||||
// this is taken from default.frag
|
||||
|
||||
|
||||
|
||||
|
||||
float dist = length(relPos);
|
||||
|
||||
// this is taken from default.frag
|
||||
vec3 n;
|
||||
float NdotL, NdotHV, fogFactor;
|
||||
vec4 color = gl_Color;
|
||||
|
@ -146,347 +154,362 @@ void main()
|
|||
vec4 specular = vec4(0.0);
|
||||
float intensity;
|
||||
|
||||
|
||||
// get noise at different wavelengths
|
||||
|
||||
// used: 5m, 5m gradient, 10m, 10m gradient: heightmap of the closeup terrain, 10m also snow
|
||||
// 50m: detail texel
|
||||
// 250m: detail texel
|
||||
// 500m: distortion and overlay
|
||||
// 1500m: overlay, detail, dust, fog
|
||||
// 2000m: overlay, detail, snow, fog
|
||||
|
||||
float noise_10m;
|
||||
float noise_5m;
|
||||
noise_10m = Noise2D(rawPos.xy, 10.0);
|
||||
noise_5m = Noise2D(rawPos.xy ,5.0);
|
||||
|
||||
float noisegrad_10m;
|
||||
float noisegrad_5m;
|
||||
|
||||
float noise_50m;
|
||||
float noise_250m;
|
||||
float noise_500m = Noise2D(rawPos.xy, 500.0);
|
||||
float noise_1500m = Noise2D(rawPos.xy, 1500.0);
|
||||
float noise_2000m = Noise2D(rawPos.xy, 2000.0);
|
||||
|
||||
//
|
||||
// get the texels
|
||||
|
||||
|
||||
// get noise at different wavelengths
|
||||
|
||||
// used: 5m, 5m gradient, 10m, 10m gradient: heightmap of the closeup terrain, 10m also snow
|
||||
// 50m: detail texel
|
||||
// 250m: detail texel
|
||||
// 500m: distortion and overlay
|
||||
// 1500m: overlay, detail, dust, fog
|
||||
// 2000m: overlay, detail, snow, fog
|
||||
|
||||
float noise_10m;
|
||||
float noise_5m;
|
||||
noise_10m = Noise2D(rawPos.xy, 10.0);
|
||||
noise_5m = Noise2D(rawPos.xy ,5.0);
|
||||
|
||||
float noisegrad_10m;
|
||||
float noisegrad_5m;
|
||||
|
||||
float noise_50m;
|
||||
float noise_250m;
|
||||
float noise_500m = Noise2D(rawPos.xy, 500.0);
|
||||
float noise_1500m = Noise2D(rawPos.xy, 1500.0);
|
||||
float noise_2000m = Noise2D(rawPos.xy, 2000.0);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
||||
// get the texels
|
||||
|
||||
texel = texture2D(texture, gl_TexCoord[0].st);
|
||||
|
||||
|
||||
float distortion_factor = 1.0;
|
||||
vec2 stprime;
|
||||
int flag = 1;
|
||||
int mix_flag = 1;
|
||||
|
||||
|
||||
if (quality_level > 3)
|
||||
{
|
||||
snow_texel = texture2D(snow_texture, gl_TexCoord[0].st);
|
||||
snow_texel = texture2D(snow_texture, gl_TexCoord[0].st);
|
||||
//snow_texel = vec4 (0.9, 0.9, 0.95, 1.0) * (0.8 + 0.2* noise_500m + 0.1* (1.0 - noise_10m) );
|
||||
}
|
||||
|
||||
|
||||
if (tquality_level > 2)
|
||||
{
|
||||
mix_texel = texture2D(mix_texture, gl_TexCoord[0].st * 1.3);
|
||||
if (mix_texel.a <0.1) {mix_flag = 0;}
|
||||
}
|
||||
|
||||
|
||||
if (tquality_level > 3)
|
||||
mix_texel = texture2D(mix_texture, gl_TexCoord[0].st * 1.3);
|
||||
if (mix_texel.a <0.1) {mix_flag = 0;}
|
||||
}
|
||||
|
||||
|
||||
if (tquality_level > 3)
|
||||
{
|
||||
stprime = vec2 (0.86*gl_TexCoord[0].s + 0.5*gl_TexCoord[0].t, 0.5*gl_TexCoord[0].s - 0.86*gl_TexCoord[0].t);
|
||||
//distortion_factor = 0.9375 + (1.0 * nvL[2]);
|
||||
distortion_factor = 0.97 + 0.06 * noise_500m;
|
||||
stprime = stprime * distortion_factor * 15.0;
|
||||
if (quality_level > 4)
|
||||
stprime = vec2 (0.86*gl_TexCoord[0].s + 0.5*gl_TexCoord[0].t, 0.5*gl_TexCoord[0].s - 0.86*gl_TexCoord[0].t);
|
||||
//distortion_factor = 0.9375 + (1.0 * nvL[2]);
|
||||
distortion_factor = 0.97 + 0.06 * noise_500m;
|
||||
stprime = stprime * distortion_factor * 15.0;
|
||||
if (quality_level > 4)
|
||||
{
|
||||
stprime = stprime + normalize(relPos).xy * 0.02 * (noise_10m + 0.5 * noise_5m - 0.75);
|
||||
stprime = stprime + normalize(relPos).xy * 0.02 * (noise_10m + 0.5 * noise_5m - 0.75);
|
||||
}
|
||||
detail_texel = texture2D(detail_texture, stprime);
|
||||
if (detail_texel.a <0.1) {flag = 0;}
|
||||
detail_texel = texture2D(detail_texture, stprime);
|
||||
if (detail_texel.a <0.1) {flag = 0;}
|
||||
}
|
||||
|
||||
|
||||
// texture preparation according to detail level
|
||||
|
||||
// mix in hires texture patches
|
||||
|
||||
float dist_fact;
|
||||
float nSum;
|
||||
float mix_factor;
|
||||
|
||||
if (tquality_level > 2)
|
||||
|
||||
|
||||
// texture preparation according to detail level
|
||||
|
||||
// mix in hires texture patches
|
||||
|
||||
float dist_fact;
|
||||
float nSum;
|
||||
float mix_factor;
|
||||
|
||||
if (tquality_level > 2)
|
||||
{
|
||||
// first the second texture overlay
|
||||
|
||||
|
||||
if (mix_flag == 1)
|
||||
{
|
||||
// first the second texture overlay
|
||||
|
||||
|
||||
if (mix_flag == 1)
|
||||
{
|
||||
nSum = nSum + 0.2 * (2.0 * noise_2000m + 2.0 * noise_1500m + noise_500m);
|
||||
nSum = nSum + 0.2 * (1.0 -smoothstep(0.9,0.95, abs(steepness)));
|
||||
mix_factor = smoothstep(0.5, 0.54, nSum);
|
||||
texel = mix(texel, mix_texel, mix_factor);
|
||||
}
|
||||
|
||||
// then the detail texture overlay
|
||||
nSum = 0.18 * (2.0 * noise_2000m + 2.0 * noise_1500m + noise_500m);
|
||||
nSum = nSum + 0.4 * (1.0 -smoothstep(0.9,0.95, abs(steepness)));
|
||||
mix_factor = smoothstep(0.5, 0.54, nSum);
|
||||
texel = mix(texel, mix_texel, mix_factor);
|
||||
|
||||
}
|
||||
|
||||
if (tquality_level > 3)
|
||||
{
|
||||
if (dist < 40000.0)
|
||||
|
||||
// then the detail texture overlay
|
||||
}
|
||||
|
||||
if (tquality_level > 3)
|
||||
{
|
||||
if (dist < 40000.0)
|
||||
{
|
||||
if (flag == 1)
|
||||
{
|
||||
if (flag == 1)
|
||||
{
|
||||
noise_50m = Noise2D(rawPos.xy, 50.0);
|
||||
noise_250m = Noise2D(rawPos.xy, 250.0);
|
||||
dist_fact = 0.1 * smoothstep(15000.0,40000.0, dist) - 0.03 * (1.0 - smoothstep(500.0,5000.0, dist));
|
||||
nSum = ((1.0 -noise_2000m) + noise_1500m + 2.0 * noise_250m +noise_50m)/5.0;
|
||||
nSum = nSum - 0.03 * (1.0 -smoothstep(0.9,0.95, abs(steepness)));
|
||||
mix_factor = smoothstep(0.47, 0.54, nSum - dist_fact);
|
||||
if (mix_factor > 0.8) {mix_factor = 0.8;}
|
||||
texel = mix(texel, detail_texel,mix_factor);
|
||||
}
|
||||
noise_50m = Noise2D(rawPos.xy, 50.0);
|
||||
noise_250m = Noise2D(rawPos.xy, 250.0);
|
||||
dist_fact = 0.1 * smoothstep(15000.0,40000.0, dist) - 0.03 * (1.0 - smoothstep(500.0,5000.0, dist));
|
||||
nSum = ((1.0 -noise_2000m) + noise_1500m + 2.0 * noise_250m +noise_50m)/5.0;
|
||||
nSum = nSum - 0.08 * (1.0 -smoothstep(0.9,0.95, abs(steepness)));
|
||||
mix_factor = smoothstep(0.47, 0.54, nSum - dist_fact);
|
||||
if (mix_factor > 0.8) {mix_factor = 0.8;}
|
||||
texel = mix(texel, detail_texel,mix_factor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vec4 dust_color;
|
||||
float snow_alpha;
|
||||
|
||||
if (quality_level > 3)
|
||||
}
|
||||
|
||||
|
||||
const vec4 dust_color = vec4 (0.76, 0.71, 0.56, 1.0);
|
||||
const vec4 lichen_color = vec4 (0.17, 0.20, 0.06, 1.0);;
|
||||
float snow_alpha;
|
||||
|
||||
if (quality_level > 3)
|
||||
{
|
||||
// mix dust
|
||||
dust_color = vec4 (0.76, 0.71, 0.56, 1.0);
|
||||
|
||||
texel = mix(texel, dust_color, clamp(0.5 * dust_cover_factor + 3.0 * dust_cover_factor * (((noise_1500m - 0.5) * 0.125)+0.125 ),0.0, 1.0) );
|
||||
|
||||
// mix snow
|
||||
snow_alpha = smoothstep(0.75, 0.85, abs(steepness));
|
||||
texel = mix(texel, snow_texel, smoothstep(snowlevel, snowlevel+200.0, snow_alpha * (relPos.z + eye_alt)+ (noise_2000m + 0.1 * noise_10m -0.55) *400.0));
|
||||
|
||||
// mix vegetation
|
||||
texel = mix(texel, lichen_color, 0.4 * lichen_cover_factor + 0.8 * lichen_cover_factor * 0.5 * (noise_10m + (1.0 - noise_5m)) );
|
||||
// mix dust
|
||||
texel = mix(texel, dust_color, clamp(0.5 * dust_cover_factor + 3.0 * dust_cover_factor * (((noise_1500m - 0.5) * 0.125)+0.125 ),0.0, 1.0) );
|
||||
|
||||
// mix snow
|
||||
snow_alpha = smoothstep(0.75, 0.85, abs(steepness));
|
||||
texel = mix(texel, snow_texel, smoothstep(snowlevel, snowlevel+200.0, snow_alpha * (relPos.z + eye_alt)+ (noise_2000m + 0.1 * noise_10m -0.55) *400.0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get distribution of water when terrain is wet
|
||||
|
||||
float water_threshold1;
|
||||
float water_threshold2;
|
||||
float water_factor =0.0;
|
||||
|
||||
|
||||
if ((dist < 5000.0)&& (quality_level > 3) && (wetness>0.0))
|
||||
{
|
||||
|
||||
|
||||
|
||||
// get distribution of water when terrain is wet
|
||||
|
||||
float water_threshold1;
|
||||
float water_threshold2;
|
||||
float water_factor =0.0;
|
||||
|
||||
|
||||
if ((dist < 5000.0)&& (quality_level > 3) && (wetness>0.0))
|
||||
{
|
||||
water_threshold1 = 1.0-0.5* wetness;
|
||||
water_threshold2 = 1.0 - 0.3 * wetness;
|
||||
water_factor = smoothstep(water_threshold1, water_threshold2 , (0.3 * (2.0 * (1.0-noise_10m) + (1.0 -noise_5m)) * (1.0 - smoothstep(2000.0, 5000.0, dist))) - 5.0 * (1.0 -steepness));
|
||||
}
|
||||
|
||||
// darken wet terrain
|
||||
|
||||
texel.rgb = texel.rgb * (1.0 - 0.6 * wetness);
|
||||
|
||||
|
||||
// light computations
|
||||
|
||||
|
||||
vec4 light_specular = gl_LightSource[0].specular;
|
||||
|
||||
// If gl_Color.a == 0, this is a back-facing polygon and the
|
||||
// normal should be reversed.
|
||||
n = (2.0 * gl_Color.a - 1.0) * normal;
|
||||
n = normalize(n);
|
||||
|
||||
NdotL = dot(n, lightDir);
|
||||
if ((tquality_level > 3) && (mix_flag ==1)&& (dist < 2000.0) && (quality_level > 4))
|
||||
|
||||
// darken wet terrain
|
||||
|
||||
texel.rgb = texel.rgb * (1.0 - 0.6 * wetness);
|
||||
|
||||
|
||||
// light computations
|
||||
|
||||
|
||||
vec4 light_specular = gl_LightSource[0].specular;
|
||||
|
||||
// If gl_Color.a == 0, this is a back-facing polygon and the
|
||||
// normal should be reversed.
|
||||
n = (2.0 * gl_Color.a - 1.0) * normal;
|
||||
n = normalize(n);
|
||||
|
||||
NdotL = dot(n, lightDir);
|
||||
if ((tquality_level > 3) && (mix_flag ==1)&& (dist < 2000.0) && (quality_level > 4))
|
||||
{
|
||||
noisegrad_10m = (noise_10m - Noise2D(rawPos.xy+ 0.05 * normalize(lightDir.xy),10.0))/0.05;
|
||||
noisegrad_5m = (noise_5m - Noise2D(rawPos.xy+ 0.05 * normalize(lightDir.xy),5.0))/0.05;
|
||||
NdotL = NdotL + 1.0 * (noisegrad_10m + 0.5* noisegrad_5m) * mix_factor/0.8 * (1.0 - smoothstep(1000.0, 2000.0, dist));
|
||||
noisegrad_10m = (noise_10m - Noise2D(rawPos.xy+ 0.05 * normalize(lightDir.xy),10.0))/0.05;
|
||||
noisegrad_5m = (noise_5m - Noise2D(rawPos.xy+ 0.05 * normalize(lightDir.xy),5.0))/0.05;
|
||||
NdotL = NdotL + 1.0 * (noisegrad_10m + 0.5* noisegrad_5m) * mix_factor/0.8 * (1.0 - smoothstep(1000.0, 2000.0, dist));
|
||||
}
|
||||
if (NdotL > 0.0) {
|
||||
color += diffuse_term * NdotL;
|
||||
NdotHV = max(dot(n, halfVector), 0.0);
|
||||
if (gl_FrontMaterial.shininess > 0.0) {
|
||||
specular.rgb = ((gl_FrontMaterial.specular.rgb + (water_factor * vec3 (1.0, 1.0, 1.0)))
|
||||
* light_specular.rgb
|
||||
* pow(NdotHV, gl_FrontMaterial.shininess + (20.0 * water_factor)));
|
||||
}
|
||||
}
|
||||
color.a = diffuse_term.a;
|
||||
// This shouldn't be necessary, but our lighting becomes very
|
||||
// saturated. Clamping the color before modulating by the texture
|
||||
// is closer to what the OpenGL fixed function pipeline does.
|
||||
color = clamp(color, 0.0, 1.0);
|
||||
|
||||
|
||||
|
||||
|
||||
fragColor = color * texel + specular;
|
||||
|
||||
// here comes the terrain haze model
|
||||
|
||||
|
||||
float delta_z = hazeLayerAltitude - eye_alt;
|
||||
|
||||
if (dist > max(40.0, 0.04 * min(visibility,avisibility)))
|
||||
//if ((gl_FragCoord.y > ylimit) || (gl_FragCoord.x < zlimit1) || (gl_FragCoord.x > zlimit2))
|
||||
//if (dist > 40.0)
|
||||
if (NdotL > 0.0) {
|
||||
color += diffuse_term * NdotL;
|
||||
NdotHV = max(dot(n, halfVector), 0.0);
|
||||
if (gl_FrontMaterial.shininess > 0.0)
|
||||
specular.rgb = ((gl_FrontMaterial.specular.rgb + (water_factor * vec3 (1.0, 1.0, 1.0)))
|
||||
* light_specular.rgb
|
||||
* pow(NdotHV, gl_FrontMaterial.shininess + (20.0 * water_factor)));
|
||||
}
|
||||
color.a = diffuse_term.a;
|
||||
// This shouldn't be necessary, but our lighting becomes very
|
||||
// saturated. Clamping the color before modulating by the texture
|
||||
// is closer to what the OpenGL fixed function pipeline does.
|
||||
color = clamp(color, 0.0, 1.0);
|
||||
|
||||
|
||||
|
||||
|
||||
fragColor = color * texel + specular;
|
||||
|
||||
// here comes the terrain haze model
|
||||
|
||||
|
||||
float delta_z = hazeLayerAltitude - eye_alt;
|
||||
|
||||
if (dist > max(40.0, 0.04 * min(visibility,avisibility)))
|
||||
//if ((gl_FragCoord.y > ylimit) || (gl_FragCoord.x < zlimit1) || (gl_FragCoord.x > zlimit2))
|
||||
//if (dist > 40.0)
|
||||
{
|
||||
|
||||
alt = eye_alt;
|
||||
|
||||
|
||||
float transmission;
|
||||
float vAltitude;
|
||||
float delta_zv;
|
||||
float H;
|
||||
float distance_in_layer;
|
||||
float transmission_arg;
|
||||
|
||||
// angle with horizon
|
||||
float ct = dot(vec3(0.0, 0.0, 1.0), relPos)/dist;
|
||||
|
||||
|
||||
// we solve the geometry what part of the light path is attenuated normally and what is through the haze layer
|
||||
|
||||
if (delta_z > 0.0) // we're inside the layer
|
||||
{
|
||||
|
||||
alt = eye_alt;
|
||||
|
||||
|
||||
float transmission;
|
||||
float vAltitude;
|
||||
float delta_zv;
|
||||
float H;
|
||||
float distance_in_layer;
|
||||
float transmission_arg;
|
||||
|
||||
// angle with horizon
|
||||
float ct = dot(vec3(0.0, 0.0, 1.0), relPos)/dist;
|
||||
|
||||
|
||||
// we solve the geometry what part of the light path is attenuated normally and what is through the haze layer
|
||||
|
||||
if (delta_z > 0.0) // we're inside the layer
|
||||
if (ct < 0.0) // we look down
|
||||
{
|
||||
if (ct < 0.0) // we look down
|
||||
{
|
||||
distance_in_layer = dist;
|
||||
vAltitude = min(distance_in_layer,min(visibility, avisibility)) * ct;
|
||||
delta_zv = delta_z - vAltitude;
|
||||
}
|
||||
else // we may look through upper layer edge
|
||||
{
|
||||
H = dist * ct;
|
||||
if (H > delta_z) {
|
||||
distance_in_layer = dist/H * delta_z;
|
||||
}
|
||||
else {
|
||||
distance_in_layer = dist;
|
||||
}
|
||||
vAltitude = min(distance_in_layer,visibility) * ct;
|
||||
delta_zv = delta_z - vAltitude;
|
||||
}
|
||||
distance_in_layer = dist;
|
||||
vAltitude = min(distance_in_layer,min(visibility, avisibility)) * ct;
|
||||
delta_zv = delta_z - vAltitude;
|
||||
}
|
||||
else // we see the layer from above, delta_z < 0.0
|
||||
{
|
||||
H = dist * -ct;
|
||||
if (H < (-delta_z)) // we don't see into the layer at all, aloft visibility is the only fading
|
||||
{
|
||||
distance_in_layer = 0.0;
|
||||
delta_zv = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vAltitude = H + delta_z;
|
||||
distance_in_layer = vAltitude/H * dist;
|
||||
vAltitude = min(distance_in_layer,visibility) * (-ct);
|
||||
delta_zv = vAltitude;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ground haze cannot be thinner than aloft visibility in the model,
|
||||
// so we need to use aloft visibility otherwise
|
||||
|
||||
|
||||
transmission_arg = (dist-distance_in_layer)/avisibility;
|
||||
|
||||
|
||||
float eqColorFactor;
|
||||
|
||||
|
||||
|
||||
if (visibility < avisibility)
|
||||
else // we may look through upper layer edge
|
||||
{
|
||||
if (quality_level > 3)
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/(1.0 * visibility + 1.0 * visibility * fogstructure * 0.06 * (noise_1500m + noise_2000m -1.0) ));
|
||||
}
|
||||
else
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/visibility);
|
||||
}
|
||||
// this combines the Weber-Fechner intensity
|
||||
eqColorFactor = 1.0 - 0.1 * delta_zv/visibility - (1.0 -scattering);
|
||||
|
||||
H = dist * ct;
|
||||
if (H > delta_z) {distance_in_layer = dist/H * delta_z;}
|
||||
else {distance_in_layer = dist;}
|
||||
vAltitude = min(distance_in_layer,visibility) * ct;
|
||||
delta_zv = delta_z - vAltitude;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (quality_level > 3)
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/(1.0 * avisibility + 1.0 * avisibility * fogstructure * 0.06 * (noise_1500m + noise_2000m - 1.0) ));
|
||||
}
|
||||
else
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/avisibility);
|
||||
}
|
||||
// this combines the Weber-Fechner intensity
|
||||
eqColorFactor = 1.0 - 0.1 * delta_zv/avisibility - (1.0 -scattering);
|
||||
}
|
||||
|
||||
|
||||
|
||||
transmission = fog_func(transmission_arg);
|
||||
|
||||
// there's always residual intensity, we should never be driven to zero
|
||||
if (eqColorFactor < 0.2) eqColorFactor = 0.2;
|
||||
|
||||
|
||||
float lightArg = (terminator-yprime_alt)/100000.0;
|
||||
|
||||
vec3 hazeColor;
|
||||
|
||||
hazeColor.b = light_func(lightArg, 1.330e-05, 0.264, 2.527, 1.08e-05, 1.0);
|
||||
hazeColor.g = light_func(lightArg, 3.931e-06, 0.264, 3.827, 7.93e-06, 1.0);
|
||||
hazeColor.r = light_func(lightArg, 8.305e-06, 0.161, 3.827, 3.04e-05, 1.0);
|
||||
|
||||
|
||||
// now dim the light for haze
|
||||
eShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, yprime_alt) + 0.1;
|
||||
|
||||
// Mie-like factor
|
||||
|
||||
if (lightArg < 5.0)
|
||||
{
|
||||
intensity = length(hazeColor);
|
||||
float mie_magnitude = 0.5 * smoothstep(350000.0, 150000.0, terminator-sqrt(2.0 * EarthRadius * terrain_alt));
|
||||
hazeColor = intensity * ((1.0 - mie_magnitude) + mie_magnitude * mie_angle) * normalize(mix(hazeColor, vec3 (0.5, 0.58, 0.65), mie_magnitude * (0.5 - 0.5 * mie_angle)) );
|
||||
}
|
||||
|
||||
// high altitude desaturation of the haze color
|
||||
|
||||
intensity = length(hazeColor);
|
||||
hazeColor = intensity * normalize (mix(hazeColor, intensity * vec3 (1.0,1.0,1.0), 0.7* smoothstep(5000.0, 50000.0, alt)));
|
||||
|
||||
// blue hue of haze
|
||||
|
||||
hazeColor.x = hazeColor.x * 0.83;
|
||||
hazeColor.y = hazeColor.y * 0.9;
|
||||
|
||||
|
||||
// additional blue in indirect light
|
||||
float fade_out = max(0.65 - 0.3 *overcast, 0.45);
|
||||
intensity = length(hazeColor);
|
||||
hazeColor = intensity * normalize(mix(hazeColor, 1.5* vec3 (0.45, 0.6, 0.8), 1.0 -smoothstep(0.25, fade_out,eShade) ));
|
||||
|
||||
// change haze color to blue hue for strong fogging
|
||||
hazeColor = intensity * normalize(mix(hazeColor, 2.0 * vec3 (0.55, 0.6, 0.8), (1.0-smoothstep(0.3,0.8,eqColorFactor))));
|
||||
|
||||
|
||||
// reduce haze intensity when looking at shaded surfaces, only in terminator region
|
||||
|
||||
float shadow = mix( min(1.0 + dot(normal,lightDir),1.0), 1.0, 1.0-smoothstep(0.1, 0.4, transmission));
|
||||
hazeColor = mix(shadow * hazeColor, hazeColor, 0.3 + 0.7* smoothstep(250000.0, 400000.0, terminator));
|
||||
|
||||
fragColor.xyz = mix(eqColorFactor * hazeColor * eShade, fragColor.xyz,transmission);
|
||||
|
||||
gl_FragColor = fragColor;
|
||||
}
|
||||
else // if dist < threshold no fogging at all
|
||||
else // we see the layer from above, delta_z < 0.0
|
||||
{
|
||||
H = dist * -ct;
|
||||
if (H < (-delta_z)) // we don't see into the layer at all, aloft visibility is the only fading
|
||||
{
|
||||
distance_in_layer = 0.0;
|
||||
delta_zv = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vAltitude = H + delta_z;
|
||||
distance_in_layer = vAltitude/H * dist;
|
||||
vAltitude = min(distance_in_layer,visibility) * (-ct);
|
||||
delta_zv = vAltitude;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ground haze cannot be thinner than aloft visibility in the model,
|
||||
// so we need to use aloft visibility otherwise
|
||||
|
||||
|
||||
transmission_arg = (dist-distance_in_layer)/avisibility;
|
||||
|
||||
|
||||
float eqColorFactor;
|
||||
|
||||
|
||||
|
||||
if (visibility < avisibility)
|
||||
{
|
||||
gl_FragColor = fragColor;
|
||||
if (quality_level > 3)
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/(1.0 * visibility + 1.0 * visibility * fogstructure * 0.06 * (noise_1500m + noise_2000m -1.0) ));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/visibility);
|
||||
}
|
||||
// this combines the Weber-Fechner intensity
|
||||
eqColorFactor = 1.0 - 0.1 * delta_zv/visibility - (1.0 -scattering);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (quality_level > 3)
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/(1.0 * avisibility + 1.0 * avisibility * fogstructure * 0.06 * (noise_1500m + noise_2000m - 1.0) ));
|
||||
}
|
||||
else
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/avisibility);
|
||||
}
|
||||
// this combines the Weber-Fechner intensity
|
||||
eqColorFactor = 1.0 - 0.1 * delta_zv/avisibility - (1.0 -scattering);
|
||||
}
|
||||
|
||||
|
||||
|
||||
transmission = fog_func(transmission_arg);
|
||||
|
||||
// there's always residual intensity, we should never be driven to zero
|
||||
if (eqColorFactor < 0.2) eqColorFactor = 0.2;
|
||||
|
||||
|
||||
float lightArg = (terminator-yprime_alt)/100000.0;
|
||||
|
||||
vec3 hazeColor;
|
||||
|
||||
hazeColor.b = light_func(lightArg, 1.330e-05, 0.264, 2.527, 1.08e-05, 1.0);
|
||||
hazeColor.g = light_func(lightArg, 3.931e-06, 0.264, 3.827, 7.93e-06, 1.0);
|
||||
hazeColor.r = light_func(lightArg, 8.305e-06, 0.161, 3.827, 3.04e-05, 1.0);
|
||||
|
||||
|
||||
// now dim the light for haze
|
||||
eShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, yprime_alt) + 0.1;
|
||||
|
||||
// Mie-like factor
|
||||
|
||||
if (lightArg < 10.0)
|
||||
{intensity = length(hazeColor);
|
||||
float mie_magnitude = 0.5 * smoothstep(350000.0, 150000.0, terminator-sqrt(2.0 * EarthRadius * terrain_alt));
|
||||
hazeColor = intensity * ((1.0 - mie_magnitude) + mie_magnitude * mie_angle) * normalize(mix(hazeColor, vec3 (0.5, 0.58, 0.65), mie_magnitude * (0.5 - 0.5 * mie_angle)) );
|
||||
}
|
||||
|
||||
// high altitude desaturation of the haze color
|
||||
|
||||
intensity = length(hazeColor);
|
||||
hazeColor = intensity * normalize (mix(hazeColor, intensity * vec3 (1.0,1.0,1.0), 0.7* smoothstep(5000.0, 50000.0, alt)));
|
||||
|
||||
// blue hue of haze
|
||||
|
||||
hazeColor.x = hazeColor.x * 0.83;
|
||||
hazeColor.y = hazeColor.y * 0.9;
|
||||
|
||||
|
||||
// additional blue in indirect light
|
||||
float fade_out = max(0.65 - 0.3 *overcast, 0.45);
|
||||
intensity = length(hazeColor);
|
||||
hazeColor = intensity * normalize(mix(hazeColor, 1.5* vec3 (0.45, 0.6, 0.8), 1.0 -smoothstep(0.25, fade_out,eShade) ));
|
||||
|
||||
// change haze color to blue hue for strong fogging
|
||||
hazeColor = intensity * normalize(mix(hazeColor, 2.0 * vec3 (0.55, 0.6, 0.8), (1.0-smoothstep(0.3,0.8,eqColorFactor))));
|
||||
|
||||
|
||||
// reduce haze intensity when looking at shaded surfaces, only in terminator region
|
||||
|
||||
float shadow = mix( min(1.0 + dot(normal,lightDir),1.0), 1.0, 1.0-smoothstep(0.1, 0.4, transmission));
|
||||
hazeColor = mix(shadow * hazeColor, hazeColor, 0.3 + 0.7* smoothstep(250000.0, 400000.0, terminator));
|
||||
|
||||
|
||||
|
||||
|
||||
fragColor.xyz = mix(eqColorFactor * hazeColor * eShade, fragColor.xyz,transmission);
|
||||
|
||||
|
||||
gl_FragColor = fragColor;
|
||||
|
||||
|
||||
}
|
||||
else // if dist < threshold no fogging at all
|
||||
{
|
||||
gl_FragColor = fragColor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ if (terminator < 1000000.0) // the full, sunrise and sunset computation
|
|||
lightArg = (terminator-yprime_alt)/100000.0;
|
||||
|
||||
// directional scattering for low sun
|
||||
if (lightArg < 5.0)
|
||||
if (lightArg < 10.0)
|
||||
{mie_angle = (0.5 * dot(normalize(relPos), normalize(lightFull)) ) + 0.5;}
|
||||
else
|
||||
{mie_angle = 1.0;}
|
||||
|
|
|
@ -22,7 +22,9 @@ uniform float terrain_alt;
|
|||
uniform float hazeLayerAltitude;
|
||||
uniform float overcast;
|
||||
uniform float eye_alt;
|
||||
uniform float dust_cover_factor;
|
||||
|
||||
uniform int quality_level;
|
||||
|
||||
const float EarthRadius = 5800000.0;
|
||||
const float terminator_width = 200000.0;
|
||||
|
@ -88,6 +90,13 @@ void main()
|
|||
vec4 fragColor = gl_Color * texture2D(texture, gl_TexCoord[0].st);
|
||||
|
||||
|
||||
if (quality_level > 3)
|
||||
{
|
||||
// mix dust
|
||||
vec4 dust_color = vec4 (0.76, 0.71, 0.56, fragColor.a);
|
||||
|
||||
fragColor = mix(fragColor, dust_color, clamp(0.6 * dust_cover_factor ,0.0, 1.0) );
|
||||
}
|
||||
|
||||
// here comes the terrain haze model
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ varying vec4 waterTex1; //moving texcoords
|
|||
varying vec4 waterTex2; //moving texcoords
|
||||
varying vec3 viewerdir;
|
||||
varying vec3 normal;
|
||||
varying vec3 Vnormal;
|
||||
varying vec3 rawNormal;
|
||||
varying vec3 VTangent;
|
||||
varying vec3 VBinormal;
|
||||
|
||||
|
@ -65,7 +65,7 @@ void main(void)
|
|||
vec3 E = normalize(viewerdir);
|
||||
|
||||
vec3 Normal = normalize(normal);
|
||||
vec3 vNormal = normalize(Vnormal);
|
||||
vec3 vNormal = normalize(rawNormal);
|
||||
|
||||
const float water_shininess = 240.0;
|
||||
|
||||
|
@ -171,7 +171,8 @@ void main(void)
|
|||
|
||||
vec3 N2 = normalize(mix(N0, N1, mixFactor) * waveRoughness);
|
||||
Normal = normalize(N2.x * VTangent + N2.y * VBinormal + N2.z * Normal);
|
||||
vNormal = normalize(mix(vNormal + N0, vNormal + N1, mixFactor) * waveRoughness);
|
||||
//vNormal = normalize(mix(vNormal + N0, vNormal + N1, mixFactor) * waveRoughness);
|
||||
vNormal = normalize(N2.x * vec3(1.,0.,0.) + N2.y * vec3(0.,1.,0.) + N2.z * vNormal);
|
||||
|
||||
if (normalmap_dds > 0){
|
||||
Normal = -Normal; //dds fix
|
||||
|
|
|
@ -13,6 +13,7 @@ varying vec4 waterTex2;
|
|||
varying vec3 viewerdir;
|
||||
varying vec3 lightdir;
|
||||
varying vec3 normal;
|
||||
varying vec3 rawNormal;
|
||||
|
||||
varying vec3 VTangent;
|
||||
varying vec3 VBinormal;
|
||||
|
@ -37,6 +38,7 @@ void rotationmatrix(in float angle, out mat4 rotmat)
|
|||
void main(void)
|
||||
{
|
||||
mat4 RotationMatrix;
|
||||
rawNormal= gl_Normal;
|
||||
normal = gl_NormalMatrix * gl_Normal;
|
||||
VTangent = normalize(gl_NormalMatrix * tangent);
|
||||
VBinormal = normalize(gl_NormalMatrix * binormal);
|
||||
|
|
|
@ -163,11 +163,11 @@ if (terminator < 1000000.0) // the full, sunrise and sunset computation
|
|||
if (earthShade < 0.5)
|
||||
{
|
||||
intensity = length(specular_light.rgb);
|
||||
specular_light.xyz = intensity * normalize(mix(specular_light.xyz, vec3 (0.45, 0.6, 0.8), 1.0 -smoothstep(0.1, 0.5,earthShade) ));
|
||||
specular_light.xyz = intensity * normalize(mix(specular_light.xyz, vec3 (0.45, 0.6, 0.8), 1.0 -smoothstep(0.1, 0.7,earthShade) ));
|
||||
}
|
||||
|
||||
// directional scattering for low sun
|
||||
if (lightArg < 5.0)
|
||||
if (lightArg < 10.0)
|
||||
//{mie_angle = (0.5 * dot(normalize(relPos), normalize(lightFull)) ) + 0.5;}
|
||||
{mie_angle = (0.5 * dot(normalize(relPos), lightdir) ) + 0.5;}
|
||||
else
|
||||
|
|
567
Shaders/water_lightfield_lr.frag
Normal file
567
Shaders/water_lightfield_lr.frag
Normal file
|
@ -0,0 +1,567 @@
|
|||
// 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
|
||||
// Major update and revisions - 2011-10-07
|
||||
// © Emilian Huminiuc and Vivian Meazza
|
||||
// ported to lightfield shading Thorsten Renk 2012
|
||||
|
||||
#version 120
|
||||
|
||||
uniform sampler2D water_normalmap;
|
||||
uniform sampler2D water_dudvmap;
|
||||
uniform sampler2D sea_foam;
|
||||
uniform sampler2D perlin_normalmap;
|
||||
|
||||
uniform sampler3D Noise;
|
||||
|
||||
uniform float saturation, Overcast, WindE, WindN;
|
||||
uniform float osg_SimulationTime;
|
||||
|
||||
varying vec4 waterTex1; //moving texcoords
|
||||
varying vec4 waterTex2; //moving texcoords
|
||||
varying vec4 waterTex4; //viewts
|
||||
varying vec3 viewerdir;
|
||||
varying vec3 lightdir;
|
||||
varying vec3 specular_light;
|
||||
varying vec3 relPos;
|
||||
|
||||
varying float earthShade;
|
||||
varying float yprime_alt;
|
||||
varying float mie_angle;
|
||||
|
||||
uniform float WaveFreq ;
|
||||
uniform float WaveAmp ;
|
||||
uniform float WaveSharp ;
|
||||
uniform float WaveAngle ;
|
||||
uniform float WaveFactor ;
|
||||
uniform float WaveDAngle ;
|
||||
uniform float normalmap_dds;
|
||||
|
||||
|
||||
uniform float hazeLayerAltitude;
|
||||
uniform float terminator;
|
||||
uniform float terrain_alt;
|
||||
uniform float avisibility;
|
||||
uniform float visibility;
|
||||
uniform float overcast;
|
||||
uniform float scattering;
|
||||
uniform float ground_scattering;
|
||||
uniform float eye_alt;
|
||||
uniform float sea_r;
|
||||
uniform float sea_g;
|
||||
uniform float sea_b;
|
||||
uniform float ylimit;
|
||||
uniform float zlimit1;
|
||||
uniform float zlimit2;
|
||||
|
||||
//uniform int wquality_level;
|
||||
|
||||
const float terminator_width = 200000.0;
|
||||
const float EarthRadius = 5800000.0;
|
||||
////fog "include" /////
|
||||
//uniform int fogType;
|
||||
|
||||
vec3 fog_Func(vec3 color, int type);
|
||||
//////////////////////
|
||||
|
||||
/////// functions /////////
|
||||
|
||||
void rotationmatrix(in float angle, out mat4 rotmat)
|
||||
{
|
||||
rotmat = mat4( cos( angle ), -sin( angle ), 0.0, 0.0,
|
||||
sin( angle ), cos( angle ), 0.0, 0.0,
|
||||
0.0 , 0.0 , 1.0, 0.0,
|
||||
0.0 , 0.0 , 0.0, 1.0 );
|
||||
}
|
||||
|
||||
// wave functions ///////////////////////
|
||||
|
||||
struct Wave {
|
||||
float freq; // 2*PI / wavelength
|
||||
float amp; // amplitude
|
||||
float phase; // speed * 2*PI / wavelength
|
||||
vec2 dir;
|
||||
};
|
||||
|
||||
Wave wave0 = Wave(1.0, 1.0, 0.5, vec2(0.97, 0.25));
|
||||
Wave wave1 = Wave(2.0, 0.5, 1.3, vec2(0.97, -0.25));
|
||||
Wave wave2 = Wave(1.0, 1.0, 0.6, vec2(0.95, -0.3));
|
||||
Wave wave3 = Wave(2.0, 0.5, 1.4, vec2(0.99, 0.1));
|
||||
|
||||
|
||||
|
||||
|
||||
float evaluateWave(in Wave w, vec2 pos, float t)
|
||||
{
|
||||
return w.amp * sin( dot(w.dir, pos) * w.freq + t * w.phase);
|
||||
}
|
||||
|
||||
// derivative of wave function
|
||||
float evaluateWaveDeriv(Wave w, vec2 pos, float t)
|
||||
{
|
||||
return w.freq * w.amp * cos( dot(w.dir, pos)*w.freq + t*w.phase);
|
||||
}
|
||||
|
||||
// sharp wave functions
|
||||
float evaluateWaveSharp(Wave w, vec2 pos, float t, float k)
|
||||
{
|
||||
return w.amp * pow(sin( dot(w.dir, pos)*w.freq + t*w.phase)* 0.5 + 0.5 , k);
|
||||
}
|
||||
|
||||
float evaluateWaveDerivSharp(Wave w, vec2 pos, float t, float k)
|
||||
{
|
||||
return k*w.freq*w.amp * pow(sin( dot(w.dir, pos)*w.freq + t*w.phase)* 0.5 + 0.5 , k - 1) * cos( dot(w.dir, pos)*w.freq + t*w.phase);
|
||||
}
|
||||
|
||||
void sumWaves(float angle, float dangle, float windScale, float factor, out float ddx, float ddy)
|
||||
{
|
||||
mat4 RotationMatrix;
|
||||
float deriv;
|
||||
vec4 P = waterTex1 * 1024;
|
||||
|
||||
rotationmatrix(radians(angle + dangle * windScale + 0.6 * sin(P.x * factor)), RotationMatrix);
|
||||
P *= RotationMatrix;
|
||||
|
||||
P.y += evaluateWave(wave0, P.xz, osg_SimulationTime);
|
||||
deriv = evaluateWaveDeriv(wave0, P.xz, osg_SimulationTime );
|
||||
ddx = deriv * wave0.dir.x;
|
||||
ddy = deriv * wave0.dir.y;
|
||||
|
||||
P.y += evaluateWave(wave1, P.xz, osg_SimulationTime);
|
||||
deriv = evaluateWaveDeriv(wave1, P.xz, osg_SimulationTime);
|
||||
ddx += deriv * wave1.dir.x;
|
||||
ddy += deriv * wave1.dir.y;
|
||||
|
||||
P.y += evaluateWaveSharp(wave2, P.xz, osg_SimulationTime, WaveSharp);
|
||||
deriv = evaluateWaveDerivSharp(wave2, P.xz, osg_SimulationTime, WaveSharp);
|
||||
ddx += deriv * wave2.dir.x;
|
||||
ddy += deriv * wave2.dir.y;
|
||||
|
||||
//P.y += evaluateWaveSharp(wave3, P.xz, osg_SimulationTime, WaveSharp);
|
||||
//deriv = evaluateWaveDerivSharp(wave3, P.xz, osg_SimulationTime, WaveSharp);
|
||||
//ddx += deriv * wave3.dir.x;
|
||||
//ddy += deriv * wave3.dir.y;
|
||||
}
|
||||
|
||||
|
||||
float light_func (in float x, in float a, in float b, in float c, in float d, in float e)
|
||||
{
|
||||
x = x - 0.5;
|
||||
|
||||
// use the asymptotics to shorten computations
|
||||
if (x > 30.0) {return e;}
|
||||
if (x < -15.0) {return 0.0;}
|
||||
|
||||
return e / pow((1.0 + a * exp(-b * (x-c)) ),(1.0/d));
|
||||
}
|
||||
|
||||
// this determines how light is attenuated in the distance
|
||||
// physically this should be exp(-arg) but for technical reasons we use a sharper cutoff
|
||||
// for distance > visibility
|
||||
|
||||
float fog_func (in float targ)
|
||||
{
|
||||
|
||||
|
||||
float fade_mix;
|
||||
|
||||
// for large altitude > 30 km, we switch to some component of quadratic distance fading to
|
||||
// create the illusion of improved visibility range
|
||||
|
||||
targ = 1.25 * targ; // need to sync with the distance to which terrain is drawn
|
||||
|
||||
|
||||
if (eye_alt < 30000.0)
|
||||
{return exp(-targ - targ * targ * targ * targ);}
|
||||
else if (eye_alt < 50000.0)
|
||||
{
|
||||
fade_mix = (eye_alt - 30000.0)/20000.0;
|
||||
return fade_mix * exp(-targ*targ - pow(targ,4.0)) + (1.0 - fade_mix) * exp(-targ - pow(targ,4.0));
|
||||
}
|
||||
else
|
||||
{
|
||||
return exp(- targ * targ - pow(targ,4.0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
|
||||
|
||||
|
||||
if ((gl_FragCoord.y < ylimit) && (gl_FragCoord.x > zlimit1) && (gl_FragCoord.x < zlimit2))
|
||||
{discard;}
|
||||
|
||||
|
||||
float dist = length(relPos);
|
||||
const vec4 sca = vec4(0.005, 0.005, 0.005, 0.005);
|
||||
const vec4 sca2 = vec4(0.02, 0.02, 0.02, 0.02);
|
||||
const vec4 tscale = vec4(0.25, 0.25, 0.25, 0.25);
|
||||
|
||||
mat4 RotationMatrix;
|
||||
|
||||
// compute direction to viewer
|
||||
vec3 E = normalize(viewerdir);
|
||||
|
||||
// compute direction to light source
|
||||
vec3 L = lightdir; // normalize(lightdir);
|
||||
|
||||
// half vector
|
||||
vec3 Hv = normalize(L + E);
|
||||
|
||||
//vec3 Normal = normalize(normal);
|
||||
vec3 Normal = vec3 (0.0, 0.0, 1.0);
|
||||
|
||||
const float water_shininess = 240.0;
|
||||
|
||||
// approximate cloud cover
|
||||
//float cover = 0.0;
|
||||
//bool Status = true;
|
||||
|
||||
float windEffect = sqrt( WindE*WindE + WindN*WindN ) * 0.6; //wind speed in kt
|
||||
float windScale = 15.0/(3.0 + windEffect); //wave scale
|
||||
float windEffect_low = 0.3 + 0.7 * smoothstep(0.0, 5.0, windEffect); //low windspeed wave filter
|
||||
float waveRoughness = 0.01 + smoothstep(0.0, 40.0, windEffect); //wave roughness filter
|
||||
|
||||
float mixFactor = 0.2 + 0.02 * smoothstep(0.0, 50.0, windEffect);
|
||||
//mixFactor = 0.2;
|
||||
mixFactor = clamp(mixFactor, 0.3, 0.8);
|
||||
|
||||
// there's no need to do wave patterns or foam for pixels which are so far away that we can't actually see them
|
||||
// we only need detail in the near zone or where the sun reflection is
|
||||
|
||||
int detail_flag;
|
||||
if ((dist > 15000.0) && (dot(normalize(vec3 (lightdir.x, lightdir.y, 0.0) ), normalize(relPos)) < 0.7 )) {detail_flag = 0;}
|
||||
else {detail_flag = 1;}
|
||||
|
||||
//detail_flag = 1;
|
||||
|
||||
// sine waves
|
||||
float ddx, ddx1, ddx2, ddx3, ddy, ddy1, ddy2, ddy3;
|
||||
float angle;
|
||||
if (detail_flag == 1)
|
||||
{
|
||||
angle = 0.0;
|
||||
|
||||
wave0.freq = WaveFreq ;
|
||||
wave0.amp = WaveAmp;
|
||||
wave0.dir = vec2 (0.0, 1.0); //vec2(cos(radians(angle)), sin(radians(angle)));
|
||||
|
||||
angle -= 45;
|
||||
wave1.freq = WaveFreq * 2.0 ;
|
||||
wave1.amp = WaveAmp * 1.25;
|
||||
wave1.dir = vec2(0.70710, -0.7071); //vec2(cos(radians(angle)), sin(radians(angle)));
|
||||
|
||||
angle += 30;
|
||||
wave2.freq = WaveFreq * 3.5;
|
||||
wave2.amp = WaveAmp * 0.75;
|
||||
wave2.dir = vec2(0.96592, -0.2588);// vec2(cos(radians(angle)), sin(radians(angle)));
|
||||
|
||||
//angle -= 50;
|
||||
//wave3.freq = WaveFreq * 3.0 ;
|
||||
//wave3.amp = WaveAmp * 0.75;
|
||||
//wave3.dir = vec2(0.42261, -0.9063); //vec2(cos(radians(angle)), sin(radians(angle)));
|
||||
|
||||
// sum waves
|
||||
|
||||
ddx = 0.0, ddy = 0.0;
|
||||
sumWaves(WaveAngle, -1.5, windScale, WaveFactor, ddx, ddy);
|
||||
|
||||
ddx1 = 0.0, ddy1 = 0.0;
|
||||
sumWaves(WaveAngle, 1.5, windScale, WaveFactor, ddx1, ddy1);
|
||||
|
||||
//reset the waves
|
||||
/*
|
||||
angle = 0.0;
|
||||
float waveamp = WaveAmp * 0.75;
|
||||
|
||||
wave0.freq = WaveFreq ;
|
||||
wave0.amp = waveamp;
|
||||
wave0.dir = vec2 (0.0, 1.0); //vec2(cos(radians(angle)), sin(radians(angle)));
|
||||
|
||||
angle -= 20;
|
||||
wave1.freq = WaveFreq * 2.0 ;
|
||||
wave1.amp = waveamp * 1.25;
|
||||
wave1.dir = vec2(0.93969, -0.34202);// vec2(cos(radians(angle)), sin(radians(angle)));
|
||||
|
||||
angle += 35;
|
||||
wave2.freq = WaveFreq * 3.5;
|
||||
wave2.amp = waveamp * 0.75;
|
||||
wave2.dir = vec2(0.965925, 0.25881); //vec2(cos(radians(angle)), sin(radians(angle)));
|
||||
|
||||
angle -= 45;
|
||||
wave3.freq = WaveFreq * 3.0 ;
|
||||
wave3.amp = waveamp * 0.75;
|
||||
wave3.dir = vec2(0.866025, -0.5); //vec2(cos(radians(angle)), sin(radians(angle)));
|
||||
*/
|
||||
//ddx2 = 0.0, ddy2 = 0.0;
|
||||
//sumWaves(WaveAngle + WaveDAngle, -1.5, windScale, WaveFactor, ddx2, ddy2);
|
||||
|
||||
//ddx3 = 0.0, ddy3 = 0.0;
|
||||
//sumWaves(WaveAngle + WaveDAngle, 1.5, windScale, WaveFactor, ddx3, ddy3);
|
||||
|
||||
}
|
||||
// end sine stuff
|
||||
|
||||
//cover = 5.0 * smoothstep(0.6, 1.0, scattering);
|
||||
//cover = 5.0 * ground_scattering;
|
||||
|
||||
vec4 viewt = normalize(waterTex4);
|
||||
|
||||
vec4 disdis = texture2D(water_dudvmap, vec2(waterTex2 * tscale)* windScale) * 2.0 - 1.0;
|
||||
|
||||
vec4 vNorm;
|
||||
|
||||
|
||||
//normalmaps
|
||||
vec4 nmap = texture2D(water_normalmap, vec2(waterTex1 + disdis * sca2) * windScale) * 2.0 - 1.0;
|
||||
vec4 nmap1 = texture2D(perlin_normalmap, vec2(waterTex1 + disdis * sca2) * windScale) * 2.0 - 1.0;
|
||||
|
||||
rotationmatrix(radians(3.0 * sin(osg_SimulationTime * 0.0075)), RotationMatrix);
|
||||
nmap += texture2D(water_normalmap, vec2(waterTex2 * RotationMatrix * tscale) * windScale) * 2.0 - 1.0;
|
||||
nmap1 += texture2D(perlin_normalmap, vec2(waterTex2 * RotationMatrix * tscale) * windScale) * 2.0 - 1.0;
|
||||
|
||||
nmap *= windEffect_low;
|
||||
nmap1 *= windEffect_low;
|
||||
|
||||
// mix water and noise, modulated by factor
|
||||
vNorm = normalize(mix(nmap, nmap1, mixFactor) * waveRoughness);
|
||||
if (detail_flag == 1) {vNorm.r += ddx + ddx1;}
|
||||
|
||||
if (normalmap_dds > 0)
|
||||
{vNorm = -vNorm;} //dds fix
|
||||
|
||||
|
||||
|
||||
|
||||
//load reflection
|
||||
|
||||
vec4 refl ;
|
||||
|
||||
refl.r = sea_r;
|
||||
refl.g = sea_g;
|
||||
refl.b = sea_b;
|
||||
refl.a = 1.0;
|
||||
|
||||
|
||||
float intensity;
|
||||
// de-saturate for reduced light
|
||||
refl.rgb = mix(refl.rgb, vec3 (0.248, 0.248, 0.248), 1.0 - smoothstep(0.1, 0.8, ground_scattering));
|
||||
|
||||
// de-saturate light for overcast haze
|
||||
intensity = length(refl.rgb);
|
||||
refl.rgb = mix(refl.rgb, intensity * vec3 (1.0, 1.0, 1.0), 0.5 * smoothstep(0.1, 0.9, overcast));
|
||||
|
||||
vec3 N;
|
||||
|
||||
|
||||
rotationmatrix(radians(2.0 * sin(osg_SimulationTime * 0.005)), RotationMatrix);
|
||||
vec3 N0 = vec3(texture2D(water_normalmap, vec2(waterTex2 * RotationMatrix * (tscale + sca2)) * windScale) * 2.0 - 1.0);
|
||||
vec3 N1 = vec3(texture2D(perlin_normalmap, vec2(waterTex2 * RotationMatrix * (tscale + sca2)) * windScale) * 2.0 - 1.0);
|
||||
|
||||
|
||||
N0 *= windEffect_low;
|
||||
N1 *= windEffect_low;
|
||||
|
||||
N0.r += (ddx + ddx1);
|
||||
N0.g += (ddy + ddy1);
|
||||
|
||||
N = normalize(mix(Normal + N0, Normal + N1, mixFactor) * waveRoughness);
|
||||
|
||||
if (normalmap_dds > 0)
|
||||
{N = -N;} //dds fix
|
||||
|
||||
vec3 specular_color = vec3(specular_light)
|
||||
* pow(max(0.0, dot(N, Hv)), water_shininess) * 6.0;
|
||||
vec4 specular = vec4(specular_color, 0.5);
|
||||
|
||||
specular = specular * saturation * 0.3 * earthShade ;
|
||||
|
||||
//calculate fresnel
|
||||
vec4 invfres = vec4( dot(vNorm, viewt) );
|
||||
vec4 fres = vec4(1.0) + invfres;
|
||||
refl *= fres;
|
||||
|
||||
|
||||
|
||||
vec4 ambient_light;
|
||||
|
||||
ambient_light.rgb = max(specular_light.rgb, vec3(0.1, 0.1, 0.1));
|
||||
ambient_light.a = 1.0;
|
||||
|
||||
|
||||
vec4 finalColor;
|
||||
|
||||
|
||||
|
||||
finalColor = refl + specular * smoothstep(0.3, 0.6, ground_scattering);
|
||||
|
||||
//add foam
|
||||
|
||||
if (dist < 10000.0)
|
||||
{
|
||||
float foamSlope = 0.12 + 0.1 * windScale;
|
||||
|
||||
|
||||
vec4 foam_texel = texture2D(sea_foam, vec2(waterTex2 * tscale) * 25.0);
|
||||
float waveSlope = N.g;
|
||||
|
||||
if (windEffect >= 8.0)
|
||||
if (waveSlope >= foamSlope){
|
||||
finalColor = mix(finalColor, max(finalColor, finalColor + foam_texel), smoothstep(0.01, 0.50, N.g));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
finalColor *= ambient_light;
|
||||
|
||||
|
||||
|
||||
// here comes the terrain haze model
|
||||
|
||||
|
||||
float delta_z = hazeLayerAltitude - eye_alt;
|
||||
|
||||
|
||||
|
||||
if (dist > 40.0)
|
||||
{
|
||||
|
||||
|
||||
float transmission;
|
||||
float vAltitude;
|
||||
float delta_zv;
|
||||
float H;
|
||||
float distance_in_layer;
|
||||
float transmission_arg;
|
||||
|
||||
|
||||
// angle with horizon
|
||||
float ct = dot(vec3(0.0, 0.0, 1.0), relPos)/dist;
|
||||
|
||||
|
||||
// we solve the geometry what part of the light path is attenuated normally and what is through the haze layer
|
||||
|
||||
if (delta_z > 0.0) // we're inside the layer
|
||||
{
|
||||
if (ct < 0.0) // we look down
|
||||
{
|
||||
distance_in_layer = dist;
|
||||
//lambda = visibility;
|
||||
vAltitude = min(distance_in_layer,min(visibility,avisibility)) * ct;
|
||||
delta_zv = delta_z - vAltitude;
|
||||
}
|
||||
else // we may look through upper layer edge
|
||||
{
|
||||
H = dist * ct;
|
||||
if (H > delta_z) {distance_in_layer = dist/H * delta_z;}
|
||||
else {distance_in_layer = dist;}
|
||||
//lambda = visibility;
|
||||
vAltitude = min(distance_in_layer,visibility) * ct;
|
||||
delta_zv = delta_z - vAltitude;
|
||||
}
|
||||
}
|
||||
else // we see the layer from above, delta_z < 0.0
|
||||
{
|
||||
H = dist * -ct;
|
||||
if (H < (-delta_z)) // we don't see into the layer at all, aloft visibility is the only fading
|
||||
{
|
||||
distance_in_layer = 0.0;
|
||||
delta_zv = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vAltitude = H + delta_z;
|
||||
distance_in_layer = vAltitude/H * dist;
|
||||
vAltitude = min(distance_in_layer,visibility) * (-ct);
|
||||
delta_zv = vAltitude;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ground haze cannot be thinner than aloft visibility in the model,
|
||||
// so we need to use aloft visibility otherwise
|
||||
|
||||
|
||||
transmission_arg = (dist-distance_in_layer)/avisibility;
|
||||
|
||||
|
||||
float eqColorFactor;
|
||||
|
||||
|
||||
if (visibility < avisibility)
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/visibility);
|
||||
// this combines the Weber-Fechner intensity
|
||||
eqColorFactor = 1.0 - 0.1 * delta_zv/visibility - (1.0 -scattering);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
transmission_arg = transmission_arg + (distance_in_layer/avisibility);
|
||||
// this combines the Weber-Fechner intensity
|
||||
eqColorFactor = 1.0 - 0.1 * delta_zv/avisibility - (1.0 -scattering);
|
||||
}
|
||||
|
||||
|
||||
transmission = fog_func(transmission_arg);
|
||||
|
||||
// there's always residual intensity, we should never be driven to zero
|
||||
if (eqColorFactor < 0.2) eqColorFactor = 0.2;
|
||||
|
||||
|
||||
float lightArg = (terminator-yprime_alt)/100000.0;
|
||||
|
||||
vec3 hazeColor;
|
||||
//hazeColor.rgb = specular_light.rgb;
|
||||
hazeColor.b = light_func(lightArg, 1.330e-05, 0.264, 2.527, 1.08e-05, 1.0);
|
||||
hazeColor.g = light_func(lightArg, 3.931e-06, 0.264, 3.827, 7.93e-06, 1.0);
|
||||
hazeColor.r = light_func(lightArg, 8.305e-06, 0.161, 3.827, 3.04e-05, 1.0);
|
||||
|
||||
// now dim the light for haze
|
||||
float eShade = 0.9 * smoothstep(terminator_width+ terminator, -terminator_width + terminator, yprime_alt) + 0.1;
|
||||
|
||||
// Mie-like factor
|
||||
|
||||
if (lightArg < 10.0)
|
||||
{intensity = length(hazeColor);
|
||||
float mie_magnitude = 0.5 * smoothstep(350000.0, 150000.0, terminator-sqrt(2.0 * EarthRadius * terrain_alt));
|
||||
hazeColor = intensity * ((1.0 - mie_magnitude) + mie_magnitude * mie_angle) * normalize(mix(hazeColor, vec3 (0.5, 0.58, 0.65), mie_magnitude * (0.5 - 0.5 * mie_angle)) );
|
||||
}
|
||||
|
||||
// high altitude desaturation of the haze color
|
||||
|
||||
intensity = length(hazeColor);
|
||||
hazeColor = intensity * normalize (mix(hazeColor, intensity * vec3 (1.0,1.0,1.0), 0.7* smoothstep(5000.0, 50000.0, eye_alt)));
|
||||
|
||||
// blue hue of haze
|
||||
|
||||
hazeColor.x = hazeColor.x * 0.83;
|
||||
hazeColor.y = hazeColor.y * 0.9;
|
||||
|
||||
|
||||
// additional blue in indirect light
|
||||
float fade_out = max(0.65 - 0.3 *overcast, 0.45);
|
||||
intensity = length(hazeColor);
|
||||
hazeColor = intensity * normalize(mix(hazeColor, 1.5* vec3 (0.45, 0.6, 0.8), 1.0 -smoothstep(0.25, fade_out,eShade) ));
|
||||
|
||||
// change haze color to blue hue for strong fogging
|
||||
//intensity = length(hazeColor);
|
||||
hazeColor = intensity * normalize(mix(hazeColor, 2.0 * vec3 (0.55, 0.6, 0.8), (1.0-smoothstep(0.3,0.8,eqColorFactor))));
|
||||
|
||||
|
||||
// reduce haze intensity when looking at shaded surfaces, only in terminator region
|
||||
|
||||
//float shadow = mix( min(1.0 + dot(normal,lightdir),1.0), 1.0, 1.0-smoothstep(0.1, 0.4, transmission));
|
||||
//hazeColor = mix(shadow * hazeColor, hazeColor, 0.3 + 0.7* smoothstep(250000.0, 400000.0, terminator));
|
||||
|
||||
finalColor.rgb = mix(eqColorFactor * hazeColor * eShade, finalColor.rgb,transmission);
|
||||
|
||||
|
||||
}
|
||||
gl_FragColor = finalColor;
|
||||
|
||||
}
|
|
@ -46,7 +46,7 @@ varying vec4 waterTex2 ; //moving texcoords
|
|||
varying vec3 viewerdir ;
|
||||
varying vec3 lightdir ;
|
||||
varying vec3 normal ;
|
||||
varying vec3 Vnormal ;
|
||||
varying vec3 rawNormal ;
|
||||
varying vec3 VTangent ;
|
||||
varying vec3 VBinormal ;
|
||||
|
||||
|
@ -147,8 +147,8 @@ void main(void)
|
|||
//vec3 H = normalize(L + E);
|
||||
|
||||
vec3 Normal = normalize(normal) ;
|
||||
vec3 vNormal = normalize(Vnormal) ;
|
||||
const float water_shininess = 128.0 ;
|
||||
vec3 vNormal = normalize(rawNormal) ;
|
||||
const float water_shininess = 240.0 ;
|
||||
|
||||
// float range = gl_ProjectionMatrix[3].z/(gl_FragCoord.z * -2.0 + 1.0 - gl_ProjectionMatrix[2].z);
|
||||
|
||||
|
@ -334,7 +334,8 @@ void main(void)
|
|||
N0.g += ddySum;
|
||||
vec3 N2 = normalize(mix(N0, N1, mixFactor) * waveRoughness);
|
||||
Normal = normalize(N2.x * VTangent + N2.y * VBinormal + N2.z * Normal);
|
||||
vNormal = normalize(mix(vNormal + N0, vNormal + N1, mixFactor) * waveRoughness);
|
||||
//vNormal = normalize(mix(vNormal + N0, vNormal + N1, mixFactor) * waveRoughness);
|
||||
vNormal = normalize(N2.x * vec3(1.0, 0.0, 0.0) + N2.y * vec3(0.0, 1., 0.0) + N2.z * vNormal);
|
||||
if (normalmap_dds > 0){ //dds fix
|
||||
Normal = -Normal;
|
||||
vNormal = -vNormal;
|
||||
|
@ -379,5 +380,5 @@ void main(void)
|
|||
vec3( 0.3, 0.59, 0.11 )
|
||||
);
|
||||
float specular = smoothstep(0.0, 3.5, cover);
|
||||
encode_gbuffer(Normal, finalColor.rgb, 254, specular, water_shininess, emission, gl_FragCoord.z);
|
||||
encode_gbuffer(Normal, finalColor.rgb, 254, specular, water_shininess, emission, gl_FragCoord.z);
|
||||
}
|
||||
|
|
|
@ -123,11 +123,21 @@
|
|||
<!-- Help menu -->
|
||||
<help>Hilfe</help> <!-- English: "Help" -->
|
||||
<help-browser>Hilfe (im Browser)</help-browser> <!-- English: "Help (opens in browser)" -->
|
||||
<doc-browser>Erweiterte Dokumentation</doc-browser> <!-- English: "Documentation Browser" -->
|
||||
<aircraft-keys>Flugzeug Hilfe</aircraft-keys> <!-- English: "Aircraft Help" -->
|
||||
<aircraft-checklists>Flugzeug Checklisten</aircraft-checklists> <!-- English: "Aircraft Checklists" -->
|
||||
<common-keys>Tastenbelegung (Flugzeugsteuerung)</common-keys> <!-- English: "Common Aircraft Keys" -->
|
||||
<basic-keys>Tastenbelegung (allgemein)</basic-keys> <!-- English: "Basic Simulator Keys" -->
|
||||
<joystick-info>Joystick Informationen</joystick-info> <!-- English: "Joystick Information" -->
|
||||
<tutorial-start>Tutorials</tutorial-start> <!-- English: "Tutorials" -->
|
||||
<menu-about>Über FlightGear</menu-about> <!-- English: "About" -->
|
||||
|
||||
<!-- Aircraft menu (only frequent/common custom menu entries are supported) -->
|
||||
<select-livery>Lackierung auswählen</select-livery>
|
||||
<show-hide-yokes>Steuerhorn aus-/einblenden</show-hide-yokes>
|
||||
<immatriculation>Luftfahrzeugkennzeichen</immatriculation>
|
||||
<pushback>Flugzeugschlepper</pushback>
|
||||
<autostart>Autostart</autostart>
|
||||
<tiller-steering>Bugradsteuerung</tiller-steering>
|
||||
|
||||
</PropertyList>
|
||||
|
|
38
Translations/de/sys.xml
Normal file
38
Translations/de/sys.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!-- FlightGear system messages: German language resource -->
|
||||
|
||||
<!-- ###
|
||||
### This file is automatically synchronized with the master (=English language) resource.
|
||||
### Please do not add comments, change order or restructure the file.
|
||||
###
|
||||
### To translate:
|
||||
### * Replace "???" entries with appropriate translation.
|
||||
### * Keep untranslated items unmodified (leave the "???"). English original is the
|
||||
### automatic default.
|
||||
### * Remove enclosing "<!-_ ... _->" tags for completed translations.
|
||||
### * Keep the original English text unmodified (the '<!-_ English: "..." -_>)',
|
||||
### so we know which version of the English original the translation is based upon
|
||||
### (and we can identify translations which need to be updated, when the original changes).
|
||||
### * Replace "-_" occurences with a double "-" in all translations (XML does not allow
|
||||
### consecutive "-" characters in comments).
|
||||
###
|
||||
### Last synchronized with English master resource on 2012-September-21 for FlightGear 2.9.0
|
||||
### -->
|
||||
<PropertyList>
|
||||
|
||||
<splash>
|
||||
<init>Initialisiere</init> <!-- English: "initializing" -->
|
||||
<loading-aircraft-list>Lade Flugzeugliste</loading-aircraft-list> <!-- English: "loading aircraft list" -->
|
||||
<loading-aircraft>Lade Flugzeug</loading-aircraft> <!-- English: "loading aircraft" -->
|
||||
<loading-nav-dat>Lade Navigationsdaten</loading-nav-dat> <!-- English: "loading navigation data" -->
|
||||
<init-scenery>Initialisiere Szenerie</init-scenery> <!-- English: "initializing scenery" -->
|
||||
<creating-subsystems>Erzeuge Subsysteme</creating-subsystems> <!-- English: "creating subsystems" -->
|
||||
<init-subsystems>Initialisiere Subsysteme</init-subsystems> <!-- English: "initializing subsystems" -->
|
||||
<binding-subsystems>Binde Subsysteme</binding-subsystems> <!-- English: "binding subsystems" -->
|
||||
<finishing-subsystems>Finalisiere Subsysteme</finishing-subsystems> <!-- English: "finalizing subsystems" -->
|
||||
<init-graphics>Initialisiere Grafik</init-graphics> <!-- English: "initializing graphics engine" -->
|
||||
<loading-scenery>Lade Szenerie</loading-scenery> <!-- English: "loading scenery" -->
|
||||
</splash>
|
||||
|
||||
</PropertyList>
|
|
@ -108,8 +108,9 @@
|
|||
<!-- Help menu -->
|
||||
<help>Help</help>
|
||||
<help-browser>Help (opens in browser)</help-browser>
|
||||
<doc-browser>Documentation Browser</doc-browser>
|
||||
<aircraft-keys>Aircraft Help</aircraft-keys>
|
||||
<aircraft-checklists>Aircraft Checklists</aircraft-checklists>
|
||||
<aircraft-checklists>Aircraft Checklists</aircraft-checklists>
|
||||
<common-keys>Common Aircraft Keys</common-keys>
|
||||
<basic-keys>Basic Simulator Keys</basic-keys>
|
||||
<joystick-config>Joystick Configuration</joystick-config>
|
||||
|
@ -117,4 +118,12 @@
|
|||
<tutorial-start>Tutorials</tutorial-start>
|
||||
<menu-about>About</menu-about>
|
||||
|
||||
<!-- Aircraft menu (only frequent/common custom menu entries are supported) -->
|
||||
<select-livery>Select livery</select-livery>
|
||||
<show-hide-yokes>Show/hide yokes</show-hide-yokes>
|
||||
<immatriculation>Immatriculation</immatriculation>
|
||||
<pushback>Pushback</pushback>
|
||||
<autostart>Autostart</autostart>
|
||||
<tiller-steering>Tiller Steering</tiller-steering>
|
||||
|
||||
</PropertyList>
|
||||
|
|
21
Translations/en/sys.xml
Normal file
21
Translations/en/sys.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- FlightGear system messages: English (=default) language resource -->
|
||||
|
||||
<PropertyList>
|
||||
|
||||
<splash>
|
||||
<init>initializing</init>
|
||||
<loading-aircraft-list>loading aircraft list</loading-aircraft-list>
|
||||
<loading-aircraft>loading aircraft</loading-aircraft>
|
||||
<loading-nav-dat>loading navigation data</loading-nav-dat>
|
||||
<init-scenery>initializing scenery</init-scenery>
|
||||
<creating-subsystems>creating subsystems</creating-subsystems>
|
||||
<init-subsystems>initializing subsystems</init-subsystems>
|
||||
<binding-subsystems>binding subsystems</binding-subsystems>
|
||||
<finishing-subsystems>finalizing subsystems</finishing-subsystems>
|
||||
<init-graphics>initializing graphics engine</init-graphics>
|
||||
<loading-scenery>loading scenery</loading-scenery>
|
||||
</splash>
|
||||
|
||||
</PropertyList>
|
38
Translations/es/sys.xml
Normal file
38
Translations/es/sys.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!-- FlightGear system messages: Spanish language resource -->
|
||||
|
||||
<!-- ###
|
||||
### This file is automatically synchronized with the master (=English language) resource.
|
||||
### Please do not add comments, change order or restructure the file.
|
||||
###
|
||||
### To translate:
|
||||
### * Replace "???" entries with appropriate translation.
|
||||
### * Keep untranslated items unmodified (leave the "???"). English original is the
|
||||
### automatic default.
|
||||
### * Remove enclosing "<!-_ ... _->" tags for completed translations.
|
||||
### * Keep the original English text unmodified (the '<!-_ English: "..." -_>)',
|
||||
### so we know which version of the English original the translation is based upon
|
||||
### (and we can identify translations which need to be updated, when the original changes).
|
||||
### * Replace "-_" occurences with a double "-" in all translations (XML does not allow
|
||||
### consecutive "-" characters in comments).
|
||||
###
|
||||
### Last synchronized with English master resource on 2012-September-21 for FlightGear 2.9.0
|
||||
### -->
|
||||
<PropertyList>
|
||||
|
||||
<splash>
|
||||
<!-- <init>???</init> --> <!-- English: "initializing" -->
|
||||
<!-- <loading-aircraft-list>???</loading-aircraft-list> --> <!-- English: "loading aircraft list" -->
|
||||
<!-- <loading-aircraft>???</loading-aircraft> --> <!-- English: "loading aircraft" -->
|
||||
<!-- <loading-nav-dat>???</loading-nav-dat> --> <!-- English: "loading navigation data" -->
|
||||
<!-- <init-scenery>???</init-scenery> --> <!-- English: "initializing scenery" -->
|
||||
<!-- <creating-subsystems>???</creating-subsystems> --> <!-- English: "creating subsystems" -->
|
||||
<!-- <init-subsystems>???</init-subsystems> --> <!-- English: "initializing subsystems" -->
|
||||
<!-- <binding-subsystems>???</binding-subsystems> --> <!-- English: "binding subsystems" -->
|
||||
<!-- <finishing-subsystems>???</finishing-subsystems> --> <!-- English: "finalizing subsystems" -->
|
||||
<!-- <init-graphics>???</init-graphics> --> <!-- English: "initializing graphics engine" -->
|
||||
<!-- <loading-scenery>???</loading-scenery> --> <!-- English: "loading scenery" -->
|
||||
</splash>
|
||||
|
||||
</PropertyList>
|
38
Translations/fr/sys.xml
Normal file
38
Translations/fr/sys.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!-- FlightGear system messages: French language resource -->
|
||||
|
||||
<!-- ###
|
||||
### This file is automatically synchronized with the master (=English language) resource.
|
||||
### Please do not add comments, change order or restructure the file.
|
||||
###
|
||||
### To translate:
|
||||
### * Replace "???" entries with appropriate translation.
|
||||
### * Keep untranslated items unmodified (leave the "???"). English original is the
|
||||
### automatic default.
|
||||
### * Remove enclosing "<!-_ ... _->" tags for completed translations.
|
||||
### * Keep the original English text unmodified (the '<!-_ English: "..." -_>)',
|
||||
### so we know which version of the English original the translation is based upon
|
||||
### (and we can identify translations which need to be updated, when the original changes).
|
||||
### * Replace "-_" occurences with a double "-" in all translations (XML does not allow
|
||||
### consecutive "-" characters in comments).
|
||||
###
|
||||
### Last synchronized with English master resource on 2012-September-21 for FlightGear 2.9.0
|
||||
### -->
|
||||
<PropertyList>
|
||||
|
||||
<splash>
|
||||
<init>Réinitialiser</init> <!-- English: "initializing" -->
|
||||
<!-- <loading-aircraft-list>???</loading-aircraft-list> --> <!-- English: "loading aircraft list" -->
|
||||
<!-- <loading-aircraft>???</loading-aircraft> --> <!-- English: "loading aircraft" -->
|
||||
<!-- <loading-nav-dat>???</loading-nav-dat> --> <!-- English: "loading navigation data" -->
|
||||
<!-- <init-scenery>???</init-scenery> --> <!-- English: "initializing scenery" -->
|
||||
<!-- <creating-subsystems>???</creating-subsystems> --> <!-- English: "creating subsystems" -->
|
||||
<!-- <init-subsystems>???</init-subsystems> --> <!-- English: "initializing subsystems" -->
|
||||
<!-- <binding-subsystems>???</binding-subsystems> --> <!-- English: "binding subsystems" -->
|
||||
<!-- <finishing-subsystems>???</finishing-subsystems> --> <!-- English: "finalizing subsystems" -->
|
||||
<!-- <init-graphics>???</init-graphics> --> <!-- English: "initializing graphics engine" -->
|
||||
<!-- <loading-scenery>???</loading-scenery> --> <!-- English: "loading scenery" -->
|
||||
</splash>
|
||||
|
||||
</PropertyList>
|
38
Translations/it/sys.xml
Normal file
38
Translations/it/sys.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!-- FlightGear system messages: Italian language resource -->
|
||||
|
||||
<!-- ###
|
||||
### This file is automatically synchronized with the master (=English language) resource.
|
||||
### Please do not add comments, change order or restructure the file.
|
||||
###
|
||||
### To translate:
|
||||
### * Replace "???" entries with appropriate translation.
|
||||
### * Keep untranslated items unmodified (leave the "???"). English original is the
|
||||
### automatic default.
|
||||
### * Remove enclosing "<!-_ ... _->" tags for completed translations.
|
||||
### * Keep the original English text unmodified (the '<!-_ English: "..." -_>)',
|
||||
### so we know which version of the English original the translation is based upon
|
||||
### (and we can identify translations which need to be updated, when the original changes).
|
||||
### * Replace "-_" occurences with a double "-" in all translations (XML does not allow
|
||||
### consecutive "-" characters in comments).
|
||||
###
|
||||
### Last synchronized with English master resource on 2012-September-21 for FlightGear 2.9.0
|
||||
### -->
|
||||
<PropertyList>
|
||||
|
||||
<splash>
|
||||
<!-- <init>???</init> --> <!-- English: "initializing" -->
|
||||
<!-- <loading-aircraft-list>???</loading-aircraft-list> --> <!-- English: "loading aircraft list" -->
|
||||
<!-- <loading-aircraft>???</loading-aircraft> --> <!-- English: "loading aircraft" -->
|
||||
<!-- <loading-nav-dat>???</loading-nav-dat> --> <!-- English: "loading navigation data" -->
|
||||
<!-- <init-scenery>???</init-scenery> --> <!-- English: "initializing scenery" -->
|
||||
<!-- <creating-subsystems>???</creating-subsystems> --> <!-- English: "creating subsystems" -->
|
||||
<!-- <init-subsystems>???</init-subsystems> --> <!-- English: "initializing subsystems" -->
|
||||
<!-- <binding-subsystems>???</binding-subsystems> --> <!-- English: "binding subsystems" -->
|
||||
<!-- <finishing-subsystems>???</finishing-subsystems> --> <!-- English: "finalizing subsystems" -->
|
||||
<!-- <init-graphics>???</init-graphics> --> <!-- English: "initializing graphics engine" -->
|
||||
<!-- <loading-scenery>???</loading-scenery> --> <!-- English: "loading scenery" -->
|
||||
</splash>
|
||||
|
||||
</PropertyList>
|
|
@ -15,6 +15,7 @@
|
|||
<strings>
|
||||
<options>Translations/en/options.xml</options>
|
||||
<menu>Translations/en/menu.xml</menu>
|
||||
<sys>Translations/en/sys.xml</sys>
|
||||
</strings>
|
||||
</locale>
|
||||
|
||||
|
@ -27,6 +28,7 @@
|
|||
<strings>
|
||||
<options>Translations/es/options.xml</options>
|
||||
<menu>Translations/es/menu.xml</menu>
|
||||
<sys>Translations/es/sys.xml</sys>
|
||||
</strings>
|
||||
</locale>
|
||||
|
||||
|
@ -39,6 +41,7 @@
|
|||
<strings>
|
||||
<options>Translations/de/options.xml</options>
|
||||
<menu>Translations/de/menu.xml</menu>
|
||||
<sys>Translations/de/sys.xml</sys>
|
||||
</strings>
|
||||
</locale>
|
||||
|
||||
|
@ -52,6 +55,7 @@
|
|||
<strings>
|
||||
<options>Translations/fr/options.xml</options>
|
||||
<menu>Translations/fr/menu.xml</menu>
|
||||
<sys>Translations/fr/sys.xml</sys>
|
||||
</strings>
|
||||
</locale>
|
||||
|
||||
|
@ -64,6 +68,7 @@
|
|||
<strings>
|
||||
<options>Translations/it/options.xml</options>
|
||||
<menu>Translations/it/menu.xml</menu>
|
||||
<sys>Translations/it/sys.xml</sys>
|
||||
</strings>
|
||||
</locale>
|
||||
|
||||
|
@ -75,6 +80,7 @@
|
|||
<strings>
|
||||
<options>Translations/nl/options.xml</options>
|
||||
<menu>Translations/nl/menu.xml</menu>
|
||||
<sys>Translations/nl/sys.xml</sys>
|
||||
</strings>
|
||||
</locale>
|
||||
|
||||
|
@ -85,6 +91,7 @@
|
|||
<strings>
|
||||
<options>Translations/pl/options.xml</options>
|
||||
<menu>Translations/pl/menu.xml</menu>
|
||||
<sys>Translations/pl/sys.xml</sys>
|
||||
</strings>
|
||||
</locale>
|
||||
|
||||
|
@ -104,6 +111,7 @@
|
|||
<strings>
|
||||
<options>Translations/cs/options.xml</options>
|
||||
<menu>Translations/cs/menu.xml</menu>
|
||||
<sys>Translations/cs/sys.xml</sys>
|
||||
</strings>
|
||||
</locale>
|
||||
|
||||
|
@ -113,6 +121,7 @@
|
|||
<strings>
|
||||
<options>Translations/da/options.xml</options>
|
||||
<menu>Translations/da/menu.xml</menu>
|
||||
<sys>Translations/da/sys.xml</sys>
|
||||
</strings>
|
||||
</locale>
|
||||
|
||||
|
|
41
Translations/nl/sys.xml
Normal file
41
Translations/nl/sys.xml
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!-- FlightGear system messages: Dutch language resource -->
|
||||
|
||||
<!-- ###
|
||||
### This file is automatically synchronized with the master (=English language) resource.
|
||||
### Please do not add comments, change order or restructure the file.
|
||||
###
|
||||
### To translate:
|
||||
### * Replace "???" entries with appropriate translation.
|
||||
### * Keep untranslated items unmodified (leave the "???"). English original is the
|
||||
### automatic default.
|
||||
### * Remove enclosing "<!-_ ... _->" tags for completed translations.
|
||||
### * Keep the original English text unmodified (the '<!-_ English: "..." -_>)',
|
||||
### so we know which version of the English original the translation is based upon
|
||||
### (and we can identify translations which need to be updated, when the original changes).
|
||||
### * Replace "-_" occurences with a double "-" in all translations (XML does not allow
|
||||
### consecutive "-" characters in comments).
|
||||
###
|
||||
### Last synchronized with English master resource on 2012-September-21 for FlightGear 2.9.0
|
||||
### -->
|
||||
<PropertyList>
|
||||
|
||||
<splash>
|
||||
|
||||
<!-- I know, this isn't really Dutch. Just a stub until Gijs has time to work on this new file :). -->
|
||||
|
||||
<init>initialisere</init> <!-- English: "initializing" -->
|
||||
<!-- <loading-aircraft-list>???</loading-aircraft-list> --> <!-- English: "loading aircraft list" -->
|
||||
<loading-aircraft>vliegtuig laden</loading-aircraft> <!-- English: "loading aircraft" -->
|
||||
<!-- <loading-nav-dat>???</loading-nav-dat> --> <!-- English: "loading navigation data" -->
|
||||
<!-- <init-scenery>???</init-scenery> --> <!-- English: "initializing scenery" -->
|
||||
<!-- <creating-subsystems>???</creating-subsystems> --> <!-- English: "creating subsystems" -->
|
||||
<init-subsystems>initialisere subsysteme</init-subsystems> <!-- English: "initializing subsystems" -->
|
||||
<!-- <binding-subsystems>???</binding-subsystems> --> <!-- English: "binding subsystems" -->
|
||||
<!-- <finishing-subsystems>???</finishing-subsystems> --> <!-- English: "finalizing subsystems" -->
|
||||
<init-graphics>initialisere grafiek</init-graphics> <!-- English: "initializing graphics engine" -->
|
||||
<loading-scenery>scenerie laden</loading-scenery> <!-- English: "loading scenery" -->
|
||||
</splash>
|
||||
|
||||
</PropertyList>
|
38
Translations/pl/sys.xml
Normal file
38
Translations/pl/sys.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!-- FlightGear system messages: Polish language resource -->
|
||||
|
||||
<!-- ###
|
||||
### This file is automatically synchronized with the master (=English language) resource.
|
||||
### Please do not add comments, change order or restructure the file.
|
||||
###
|
||||
### To translate:
|
||||
### * Replace "???" entries with appropriate translation.
|
||||
### * Keep untranslated items unmodified (leave the "???"). English original is the
|
||||
### automatic default.
|
||||
### * Remove enclosing "<!-_ ... _->" tags for completed translations.
|
||||
### * Keep the original English text unmodified (the '<!-_ English: "..." -_>)',
|
||||
### so we know which version of the English original the translation is based upon
|
||||
### (and we can identify translations which need to be updated, when the original changes).
|
||||
### * Replace "-_" occurences with a double "-" in all translations (XML does not allow
|
||||
### consecutive "-" characters in comments).
|
||||
###
|
||||
### Last synchronized with English master resource on 2012-September-21 for FlightGear 2.9.0
|
||||
### -->
|
||||
<PropertyList>
|
||||
|
||||
<splash>
|
||||
<!-- <init>???</init> --> <!-- English: "initializing" -->
|
||||
<!-- <loading-aircraft-list>???</loading-aircraft-list> --> <!-- English: "loading aircraft list" -->
|
||||
<!-- <loading-aircraft>???</loading-aircraft> --> <!-- English: "loading aircraft" -->
|
||||
<!-- <loading-nav-dat>???</loading-nav-dat> --> <!-- English: "loading navigation data" -->
|
||||
<!-- <init-scenery>???</init-scenery> --> <!-- English: "initializing scenery" -->
|
||||
<!-- <creating-subsystems>???</creating-subsystems> --> <!-- English: "creating subsystems" -->
|
||||
<!-- <init-subsystems>???</init-subsystems> --> <!-- English: "initializing subsystems" -->
|
||||
<!-- <binding-subsystems>???</binding-subsystems> --> <!-- English: "binding subsystems" -->
|
||||
<!-- <finishing-subsystems>???</finishing-subsystems> --> <!-- English: "finalizing subsystems" -->
|
||||
<!-- <init-graphics>???</init-graphics> --> <!-- English: "initializing graphics engine" -->
|
||||
<!-- <loading-scenery>???</loading-scenery> --> <!-- English: "loading scenery" -->
|
||||
</splash>
|
||||
|
||||
</PropertyList>
|
38
Translations/pt/sys.xml
Normal file
38
Translations/pt/sys.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!-- FlightGear system messages: Portuguese language resource -->
|
||||
|
||||
<!-- ###
|
||||
### This file is automatically synchronized with the master (=English language) resource.
|
||||
### Please do not add comments, change order or restructure the file.
|
||||
###
|
||||
### To translate:
|
||||
### * Replace "???" entries with appropriate translation.
|
||||
### * Keep untranslated items unmodified (leave the "???"). English original is the
|
||||
### automatic default.
|
||||
### * Remove enclosing "<!-_ ... _->" tags for completed translations.
|
||||
### * Keep the original English text unmodified (the '<!-_ English: "..." -_>)',
|
||||
### so we know which version of the English original the translation is based upon
|
||||
### (and we can identify translations which need to be updated, when the original changes).
|
||||
### * Replace "-_" occurences with a double "-" in all translations (XML does not allow
|
||||
### consecutive "-" characters in comments).
|
||||
###
|
||||
### Last synchronized with English master resource on 2012-September-21 for FlightGear 2.9.0
|
||||
### -->
|
||||
<PropertyList>
|
||||
|
||||
<splash>
|
||||
<!-- <init>???</init> --> <!-- English: "initializing" -->
|
||||
<!-- <loading-aircraft-list>???</loading-aircraft-list> --> <!-- English: "loading aircraft list" -->
|
||||
<!-- <loading-aircraft>???</loading-aircraft> --> <!-- English: "loading aircraft" -->
|
||||
<!-- <loading-nav-dat>???</loading-nav-dat> --> <!-- English: "loading navigation data" -->
|
||||
<!-- <init-scenery>???</init-scenery> --> <!-- English: "initializing scenery" -->
|
||||
<!-- <creating-subsystems>???</creating-subsystems> --> <!-- English: "creating subsystems" -->
|
||||
<!-- <init-subsystems>???</init-subsystems> --> <!-- English: "initializing subsystems" -->
|
||||
<!-- <binding-subsystems>???</binding-subsystems> --> <!-- English: "binding subsystems" -->
|
||||
<!-- <finishing-subsystems>???</finishing-subsystems> --> <!-- English: "finalizing subsystems" -->
|
||||
<!-- <init-graphics>???</init-graphics> --> <!-- English: "initializing graphics engine" -->
|
||||
<!-- <loading-scenery>???</loading-scenery> --> <!-- English: "loading scenery" -->
|
||||
</splash>
|
||||
|
||||
</PropertyList>
|
|
@ -24,19 +24,49 @@
|
|||
<binding>
|
||||
<command>dialog-close</command>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>property-toggle</command>
|
||||
<property>/sim/gui/dialogs/airports/signals/dialog-close</property>
|
||||
</binding>
|
||||
</button>
|
||||
</group>
|
||||
|
||||
<hrule/>
|
||||
|
||||
<nasal>
|
||||
<open>
|
||||
<!-- Generalize all this, turn into helpers and load defaults via XML -->
|
||||
<open><![CDATA[
|
||||
## "prologue" currently required by the canvas-generic-map
|
||||
var dialog_name ="airports"; #TODO: use substr() and cmdarg() to get this dynamically
|
||||
var dialog_property = func(p) return "/sim/gui/dialogs/airports/"~p; #TODO: generalize using cmdarg
|
||||
var DIALOG_CANVAS = gui.findElementByName(cmdarg(), "airport-selection");
|
||||
canvas.GenericMap.setupGUI(DIALOG_CANVAS, "canvas-control"); #TODO: this is not a method!
|
||||
## end of canvas-generic-map prologue
|
||||
|
||||
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/rwy", "");
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/parkpos", "");
|
||||
setprop("/sim/gui/dialogs/airports/mode", "search");
|
||||
setprop("/sim/gui/dialogs/airports/list", "");
|
||||
|
||||
var airport_id = getprop("/sim/presets/airport-id");
|
||||
if (airport_id == nil) { airport_id = "KSFO"; }
|
||||
if (getprop("/sim/gui/dialogs/airports/display-taxiways") == "") {
|
||||
setprop("/sim/gui/dialogs/airports/display-taxiways", "1");
|
||||
}
|
||||
|
||||
if (getprop("/sim/gui/dialogs/airports/display-parking") == "") {
|
||||
setprop("/sim/gui/dialogs/airports/display-parking", "0");
|
||||
}
|
||||
|
||||
if (getprop("/sim/gui/dialogs/airports/display-tower") == "") {
|
||||
setprop("/sim/gui/dialogs/airports/display-tower", "1");
|
||||
}
|
||||
|
||||
# Start with the closest airport
|
||||
var airport_id = airportinfo().id;
|
||||
|
||||
# Retrieve METAR
|
||||
fgcommand("request-metar", var n = props.Node.new({ "path": "/sim/gui/dialogs/airports/selected-airport/metar",
|
||||
"station": airport_id}));
|
||||
|
||||
var dlg = props.globals.getNode("/sim/gui/dialogs/airports", 1);
|
||||
var avail_runways = dlg.getNode("available-runways", 1);
|
||||
|
@ -75,12 +105,24 @@
|
|||
var info = airportinfo(airport_id);
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/id", airport_id);
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/name", info.name ~ " (" ~ airport_id ~ ")");
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/location", sprintf("%.3f / %.3f", info.lon, info.lat));
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/location", sprintf("%.3f / %.3f", info.lat, info.lon));
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/lon", info.lon);
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/elevation-ft", 3.28 * info.elevation);
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/rwy", "");
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/parkpos", "");
|
||||
|
||||
if (info.has_metar) {
|
||||
# Retrieve an updated METAR, and indicate that we've not got one currently.
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/metar/station-id", airport_id);
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/metar/time-to-live", 0);
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/metar/data", "Retrieving METAR, please wait.");
|
||||
} else {
|
||||
# This airport has no METAR. Ratehr than cancelling the retrieve-metar command, simply set the TTL
|
||||
# to a very long time so it won't over-ride our message.
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/metar/data", "No METAR available from this airport");
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/metar/time-to-live", 9999);
|
||||
}
|
||||
|
||||
var longest_runway = 0;
|
||||
var runway_string = "";
|
||||
var runways = info.runways;
|
||||
|
@ -105,6 +147,15 @@
|
|||
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/longest-runway", longest_runway);
|
||||
|
||||
var airport_pos = geo.Coord.new();
|
||||
airport_pos.set_latlon(info.lat, info.lon);
|
||||
|
||||
var pos = geo.aircraft_position();
|
||||
var dst = pos.distance_to(airport_pos) / 1852.0;
|
||||
var crs = pos.course_to(airport_pos);
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/distance-nm", dst);
|
||||
setprop("/sim/gui/dialogs/airports/selected-airport/course-deg", crs);
|
||||
|
||||
gui.dialog_update("airports", "runway-list");
|
||||
gui.dialog_update("airports", "parking-list");
|
||||
}
|
||||
|
@ -136,13 +187,18 @@
|
|||
} else {
|
||||
setprop("/sim/presets/runway", "");
|
||||
setprop("/sim/presets/parkpos", getprop("/sim/gui/dialogs/airports/selected-airport/parkpos"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
update_info();
|
||||
|
||||
]]>
|
||||
</open>
|
||||
<close>
|
||||
fgcommand("clear-metar", var n = props.Node.new({ "path": "/sim/gui/dialogs/airports/selected-airport/metar",
|
||||
"station": airport_id}));
|
||||
# map.cleanup_listeners(); #TODO: We should be setting a signal when closing the dialog, so that cleanup code can be invoked automatically
|
||||
</close>
|
||||
</nasal>
|
||||
|
||||
<group>
|
||||
|
@ -178,6 +234,11 @@
|
|||
|
||||
<button>
|
||||
<legend>Clear</legend>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>/sim/gui/dialogs/airports/mode</property>
|
||||
<value>search</value>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>/sim/gui/dialogs/airports/list</property>
|
||||
|
@ -196,6 +257,11 @@
|
|||
<button>
|
||||
<legend>Search</legend>
|
||||
<default>true</default>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>/sim/gui/dialogs/airports/mode</property>
|
||||
<value>search</value>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
<object-name>input</object-name>
|
||||
|
@ -206,25 +272,91 @@
|
|||
</binding>
|
||||
</button>
|
||||
|
||||
</group>
|
||||
<button>
|
||||
<legend>Within 100nm</legend>
|
||||
<binding>
|
||||
<command>property-assign</command>
|
||||
<property>/sim/gui/dialogs/airports/mode</property>
|
||||
<value>100nm</value>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
var airports = findAirportsWithinRange(100);
|
||||
|
||||
var list = dlg.getNode("close-airports", 1);
|
||||
|
||||
list.removeChildren("value");
|
||||
|
||||
forindex (var idx; airports) {
|
||||
list.getNode("value["~ idx ~ "]", 1).setValue(airports[idx].name ~ " (" ~ airports[idx].id ~ ")");
|
||||
}
|
||||
</script>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>dialog-update</command>
|
||||
<object-name>close-airport-list</object-name>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<airport-list>
|
||||
<name>airport-list</name>
|
||||
<pref-width>300</pref-width>
|
||||
<pref-height>260</pref-height>
|
||||
<halign>fill</halign>
|
||||
<valign>fill</valign>
|
||||
<stretch>true</stretch>
|
||||
<property>/sim/gui/dialogs/airports/list</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
<object-name>airport-list</object-name>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>listbox()</script>
|
||||
</binding>
|
||||
</airport-list>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<layout>table</layout>
|
||||
<default-padding>0</default-padding>
|
||||
|
||||
<list>
|
||||
<row>0</row><col>0</col>
|
||||
<visible>
|
||||
<equals>
|
||||
<property>/sim/gui/dialogs/airports/mode</property>
|
||||
<value>100nm</value>
|
||||
</equals>
|
||||
</visible>
|
||||
<name>close-airport-list</name>
|
||||
<pref-width>300</pref-width>
|
||||
<pref-height>260</pref-height>
|
||||
<halign>fill</halign>
|
||||
<valign>fill</valign>
|
||||
<stretch>true</stretch>
|
||||
<property>/sim/gui/dialogs/airports/list</property>
|
||||
<properties>/sim/gui/dialogs/airports/close-airports</properties>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
<object-name>close-airport-list</object-name>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>listbox()</script>
|
||||
</binding>
|
||||
</list>
|
||||
|
||||
<airport-list>
|
||||
<row>0</row><col>0</col>
|
||||
<visible>
|
||||
<equals>
|
||||
<property>/sim/gui/dialogs/airports/mode</property>
|
||||
<value>search</value>
|
||||
</equals>
|
||||
</visible>
|
||||
<name>airport-list</name>
|
||||
<pref-width>300</pref-width>
|
||||
<pref-height>260</pref-height>
|
||||
<halign>fill</halign>
|
||||
<valign>fill</valign>
|
||||
<stretch>true</stretch>
|
||||
<property>/sim/gui/dialogs/airports/list</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
<object-name>airport-list</object-name>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>listbox()</script>
|
||||
</binding>
|
||||
</airport-list>
|
||||
|
||||
</group>
|
||||
|
||||
<hrule/>
|
||||
|
||||
|
@ -234,7 +366,7 @@
|
|||
<text>
|
||||
<row>0</row>
|
||||
<col>0</col>
|
||||
<width>200</width>
|
||||
<width>100</width>
|
||||
<halign>right</halign>
|
||||
<label>Airport:</label>
|
||||
</text>
|
||||
|
@ -251,7 +383,7 @@
|
|||
<row>1</row>
|
||||
<col>0</col>
|
||||
<halign>right</halign>
|
||||
<label>Lon/Lat:</label>
|
||||
<label>Lat / Lon:</label>
|
||||
</text>
|
||||
<text>
|
||||
<row>1</row>
|
||||
|
@ -263,16 +395,16 @@
|
|||
|
||||
<text>
|
||||
<row>1</row>
|
||||
<col>3</col>
|
||||
<col>2</col>
|
||||
<halign>right</halign>
|
||||
<label>Elevation (ft):</label>
|
||||
<label>Elevation:</label>
|
||||
</text>
|
||||
<text>
|
||||
<row>1</row>
|
||||
<col>4</col>
|
||||
<col>3</col>
|
||||
<halign>left</halign>
|
||||
<live>true</live>
|
||||
<format>%.0f</format>
|
||||
<format>%.0f ft</format>
|
||||
<property>/sim/gui/dialogs/airports/selected-airport/elevation-ft</property>
|
||||
</text>
|
||||
|
||||
|
@ -280,17 +412,72 @@
|
|||
<row>2</row>
|
||||
<col>0</col>
|
||||
<halign>right</halign>
|
||||
<label>Longest runway (ft):</label>
|
||||
<label>Longest runway:</label>
|
||||
</text>
|
||||
<text>
|
||||
<row>2</row>
|
||||
<col>1</col>
|
||||
<halign>left</halign>
|
||||
<live>true</live>
|
||||
<format>%.0f</format>
|
||||
<format>%.0f ft</format>
|
||||
<property>/sim/gui/dialogs/airports/selected-airport/longest-runway</property>
|
||||
</text>
|
||||
|
||||
<text>
|
||||
<row>3</row>
|
||||
<col>0</col>
|
||||
<halign>right</halign>
|
||||
<label>Distance:</label>
|
||||
</text>
|
||||
<text>
|
||||
<row>3</row>
|
||||
<col>1</col>
|
||||
<halign>left</halign>
|
||||
<live>true</live>
|
||||
<format>%.1f nm</format>
|
||||
<property>/sim/gui/dialogs/airports/selected-airport/distance-nm</property>
|
||||
</text>
|
||||
|
||||
<text>
|
||||
<row>3</row>
|
||||
<col>2</col>
|
||||
<halign>right</halign>
|
||||
<label>Course:</label>
|
||||
</text>
|
||||
<text>
|
||||
<row>3</row>
|
||||
<col>3</col>
|
||||
<halign>left</halign>
|
||||
<live>true</live>
|
||||
<format>%.0f deg</format>
|
||||
<property>/sim/gui/dialogs/airports/selected-airport/course-deg</property>
|
||||
</text>
|
||||
|
||||
<text>
|
||||
<row>4</row>
|
||||
<col>0</col>
|
||||
<colspan>3</colspan>
|
||||
<halign>left</halign>
|
||||
<live>true</live>
|
||||
<label>METAR:</label>
|
||||
</text>
|
||||
|
||||
<textbox>
|
||||
<name>metar</name>
|
||||
<row>5</row>
|
||||
<col>0</col>
|
||||
<colspan>4</colspan>
|
||||
<halign>fill</halign>
|
||||
<stretch>true</stretch>
|
||||
<pref-width>300</pref-width>
|
||||
<pref-height>60</pref-height>
|
||||
<slider>0</slider>
|
||||
<editable>false</editable>
|
||||
<wrap>true</wrap>
|
||||
<live>true</live>
|
||||
<property>/sim/gui/dialogs/airports/selected-airport/metar/data</property>
|
||||
</textbox>
|
||||
|
||||
</group>
|
||||
|
||||
<hrule/>
|
||||
|
@ -404,8 +591,11 @@
|
|||
<group>
|
||||
<layout>vbox</layout>
|
||||
|
||||
<canvas>
|
||||
<name>map-dialog</name>
|
||||
<!-- Instantiate a generic canvas map and parametrize it via inclusion -->
|
||||
<!-- TODO: use params and aliasing -->
|
||||
<canvas include="/Nasal/canvas/generic-canvas-map.xml">
|
||||
|
||||
<name>airport-selection</name>
|
||||
<valign>fill</valign>
|
||||
<halign>fill</halign>
|
||||
<stretch>true</stretch>
|
||||
|
@ -413,161 +603,77 @@
|
|||
<pref-height>400</pref-height>
|
||||
<view n="0">600</view>
|
||||
<view n="1">400</view>
|
||||
|
||||
<nasal>
|
||||
|
||||
|
||||
<load><![CDATA[
|
||||
var my_canvas = canvas.get(cmdarg());
|
||||
my_canvas.setColorBackground(0.2, 0.5, 0.2, 0.5);
|
||||
|
||||
var root = my_canvas.createGroup();
|
||||
|
||||
var map = root.createChild("map", "map-test")
|
||||
.setTranslation(300, 200);
|
||||
|
||||
var layer_runways = map.createChild("group", "runways");
|
||||
|
||||
var updateMap = func() {
|
||||
var id = getprop("/sim/gui/dialogs/airports/selected-airport/id");
|
||||
|
||||
if (id != "") {
|
||||
var apt = airportinfo(id);
|
||||
|
||||
map.removeAllChildren();
|
||||
layer_runways = map.createChild("group", "runways");
|
||||
|
||||
var airport = canvas.AirportMap.new(apt);
|
||||
airport.build(layer_runways);
|
||||
<features>
|
||||
<!-- TODO: use params and aliases to make this shorter -->
|
||||
<!-- TODO: support styling, i.e. image sets/fonts and colors to be used -->
|
||||
<!-- this will set up individual "layers" and map them to boolean "toggle" properties -->
|
||||
<!-- providing an optional "description" tag here allows us to create all checkboxes procedurally -->
|
||||
<dialog-root>/sim/gui/dialogs/airports</dialog-root>
|
||||
<range-property>zoom</range-property>
|
||||
|
||||
map._node.getNode("ref-lat", 1).setDoubleValue(apt.lat);
|
||||
map._node.getNode("ref-lon", 1).setDoubleValue(apt.lon);
|
||||
map._node.getNode("hdg", 1).setDoubleValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
var ranges = [0.1, 0.25, 0.5, 1, 2.5, 5];
|
||||
|
||||
var updateZoom = func()
|
||||
{
|
||||
var z = getprop("/sim/gui/dialogs/airports/zoom");
|
||||
if( z == nil )
|
||||
z = 0;
|
||||
var zoom = ranges[4 - z];
|
||||
map._node.getNode("range", 1).setDoubleValue(zoom);
|
||||
|
||||
settimer(updateZoom, 0.5, 1);
|
||||
};
|
||||
|
||||
var updateRunwayHighlight = func()
|
||||
{
|
||||
var selected_rwy = getprop("/sim/gui/dialogs/airports/selected-airport/rwy");
|
||||
var selected_apt = getprop("/sim/gui/dialogs/airports/selected-airport/id");
|
||||
|
||||
var is_heli = substr(selected_rwy, 0, 1) == "H";
|
||||
var rw_dir = is_heli ? nil : int(substr(selected_rwy, 0, 2));
|
||||
|
||||
var rw_rec = "";
|
||||
if( rw_dir != nil ) {
|
||||
rw_rec = sprintf("%02d", math.mod(rw_dir - 18, 36));
|
||||
if( size(selected_rwy) == 3 ) {
|
||||
var map_rec = {
|
||||
"R": "L",
|
||||
"L": "R",
|
||||
"C": "C"
|
||||
};
|
||||
rw_rec ~= map_rec[substr(selected_rwy, 2)];
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var apt; layer_runways.getChildren()) {
|
||||
if (apt.get("id") == "apt-" ~ selected_apt) {
|
||||
foreach (var rwy; apt.getChildren()) {
|
||||
if ((rwy.get("id") == "runway-" ~ selected_rwy) or
|
||||
(rwy.get("id") == "runway-" ~ rw_rec) )
|
||||
{
|
||||
rwy.setColor(1.0,0.0,0.0);
|
||||
} else {
|
||||
rwy.setColor(1.0,1.0,1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
<!-- These are the ranges available for the map: var ranges = [0.1, 0.25, 0.5, 1, 2.5, 5] -->
|
||||
|
||||
var updateParkingHighlight = func()
|
||||
{
|
||||
var selected_parkpos = getprop("/sim/gui/dialogs/airports/selected-airport/parkpos");
|
||||
var selected_apt = getprop("/sim/gui/dialogs/airports/selected-airport/id");
|
||||
|
||||
foreach (var apt; layer_runways.getChildren()) {
|
||||
if (apt.get("id") == "apt-" ~ selected_apt) {
|
||||
foreach (var rwy; apt.getChildren()) {
|
||||
if (rwy.get("id") == "parking-" ~ selected_parkpos) {
|
||||
rwy.setColor(1.0,0.0,0.0);
|
||||
} else {
|
||||
rwy.setColor(1.0,1.0,1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var aptlistener = setlistener("/sim/gui/dialogs/airports/selected-airport/id", updateMap);
|
||||
var rwylistener = setlistener("/sim/gui/dialogs/airports/selected-airport/rwy", updateRunwayHighlight);
|
||||
var parkposlistener = setlistener("/sim/gui/dialogs/airports/selected-airport/parkpos", updateParkingHighlight);
|
||||
|
||||
update_info();
|
||||
updateZoom();
|
||||
]]>
|
||||
</load>
|
||||
<close>
|
||||
removelistener(aptlistener);
|
||||
removelistener(rwylistener);
|
||||
removelistener(parkposlistener);
|
||||
</close>
|
||||
</nasal>
|
||||
<ranges>
|
||||
<range>0.1</range>
|
||||
<range>0.25</range>
|
||||
<range>0.5</range>
|
||||
<range>1</range>
|
||||
<range>2.5</range>
|
||||
<range>5</range>
|
||||
</ranges>
|
||||
|
||||
<!-- available layers and their toggle property (appended to dialog-root specified above) -->
|
||||
|
||||
<layer>
|
||||
<name>runways</name> <!-- the name of the layer -->
|
||||
<init-property>selected-airport/id</init-property> <!-- the init/input property that re-inits the layer MODEL -->
|
||||
<property>display-runways</property> <!-- the property switch that toggles the layer on/off (show/hide) -->
|
||||
<description>Show Runways</description> <!-- the checkbox label for the property -->
|
||||
<default>enabled</default> <!-- default state -->
|
||||
<hide-checkbox>true</hide-checkbox> <!-- if the checkbox should be shown or hidden -->
|
||||
</layer>
|
||||
<layer>
|
||||
<name>taxiways</name>
|
||||
<init-property>selected-airport/id</init-property>
|
||||
<property>display-taxiways</property>
|
||||
<description>Show Taxiways</description>
|
||||
<default>disabled</default>
|
||||
</layer>
|
||||
|
||||
<layer>
|
||||
<name>parkings</name>
|
||||
<init-property>selected-airport/id</init-property>
|
||||
<property>display-parking</property>
|
||||
<description>Show Parking</description>
|
||||
<default>disabled</default>
|
||||
</layer>
|
||||
|
||||
<layer>
|
||||
<name>towers</name>
|
||||
<init-property>selected-airport/id</init-property>
|
||||
<property>display-tower</property>
|
||||
<description>Show Tower</description>
|
||||
<default>enabled</default>
|
||||
</layer>
|
||||
<!-- Uncomment this to add a navaid layer (not yet fully implemented, and no LOD yet)
|
||||
<layer>
|
||||
<name>navaids</name>
|
||||
<init-property>selected-airport/id</init-property>
|
||||
<property>display-navaids</property>
|
||||
<description>Display Navaids within current range</description>
|
||||
<default>disabled</default>
|
||||
</layer>
|
||||
-->
|
||||
|
||||
</features>
|
||||
</canvas>
|
||||
|
||||
<hrule/>
|
||||
|
||||
<group>
|
||||
<name>canvas-control</name> <!-- this is the handle we use to procedurally add all "toggle layer" checkboxes and the zoom control-->
|
||||
<layout>hbox</layout>
|
||||
|
||||
<button>
|
||||
<name>zoomout</name>
|
||||
<legend>-</legend>
|
||||
<pref-width>22</pref-width>
|
||||
<pref-height>22</pref-height>
|
||||
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property>/sim/gui/dialogs/airports/zoom</property>
|
||||
<min>0</min>
|
||||
<step>-1</step>
|
||||
</binding>
|
||||
</button>
|
||||
|
||||
<text>
|
||||
<label>MMM</label>
|
||||
<format>Zoom %d</format>
|
||||
<property>/sim/gui/dialogs/airports/zoom</property>
|
||||
<live>true</live>
|
||||
</text>
|
||||
|
||||
<button>
|
||||
<name>zoomin</name>
|
||||
<legend>+</legend>
|
||||
<pref-width>22</pref-width>
|
||||
<pref-height>22</pref-height>
|
||||
|
||||
<binding>
|
||||
<command>property-adjust</command>
|
||||
<property>//sim/gui/dialogs/airports/zoom</property>
|
||||
<step>1</step>
|
||||
<max>4</max>
|
||||
</binding>
|
||||
</button>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
@ -581,7 +687,7 @@
|
|||
<empty><stretch>true</stretch></empty>
|
||||
|
||||
<button>
|
||||
<legend>OK</legend>
|
||||
<legend>Go To Airport</legend>
|
||||
<equal>true</equal>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
|
@ -602,7 +708,7 @@
|
|||
<empty><stretch>true</stretch></empty>
|
||||
|
||||
<button>
|
||||
<legend>Cancel</legend>
|
||||
<legend>Close</legend>
|
||||
<equal>true</equal>
|
||||
<key>Esc</key>
|
||||
<binding>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<group>
|
||||
<layout>vbox</layout>
|
||||
<halign>center</halign>
|
||||
<padding>4</padding>
|
||||
|
||||
<checkbox>
|
||||
<halign>left</halign>
|
||||
|
@ -90,6 +91,7 @@
|
|||
|
||||
<group>
|
||||
<layout>hbox</layout>
|
||||
<padding>0</padding>
|
||||
|
||||
<checkbox>
|
||||
<label>Autohide cursor in</label>
|
||||
|
|
140
gui/dialogs/doc-browser.xml
Normal file
140
gui/dialogs/doc-browser.xml
Normal file
|
@ -0,0 +1,140 @@
|
|||
<?xml version="1.0"?>
|
||||
<PropertyList>
|
||||
<x>-20</x>
|
||||
<y>-20</y>
|
||||
<name>doc-browser</name>
|
||||
<dialog-name>doc-browser</dialog-name>
|
||||
<layout>vbox</layout>
|
||||
<resizable>true</resizable>
|
||||
|
||||
<group>
|
||||
<layout>hbox</layout>
|
||||
<empty>
|
||||
<stretch>1</stretch>
|
||||
</empty>
|
||||
<text>
|
||||
<label>Documentation Browser</label>
|
||||
</text>
|
||||
<empty>
|
||||
<stretch>1</stretch>
|
||||
</empty>
|
||||
<button>
|
||||
<pref-width>16</pref-width>
|
||||
<pref-height>16</pref-height>
|
||||
<legend/>
|
||||
<keynum>27</keynum>
|
||||
<border>2</border>
|
||||
<binding>
|
||||
<command>dialog-close</command>
|
||||
</binding>
|
||||
</button>
|
||||
</group>
|
||||
|
||||
<hrule/>
|
||||
|
||||
<group>
|
||||
<layout>hbox</layout>
|
||||
<list>
|
||||
<pref-width>170</pref-width>
|
||||
<pref-height>500</pref-height>
|
||||
<name>filename</name>
|
||||
<halign>fill</halign>
|
||||
<property>/sim/gui/dialogs/doc-browser/filename</property>
|
||||
<value>clear</value>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
<object-name>filename</object-name>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>dialog-update</command>
|
||||
<object-name>editfield</object-name>
|
||||
</binding>
|
||||
</list>
|
||||
<textbox>
|
||||
<name>editfield</name>
|
||||
<halign>fill</halign>
|
||||
<valign>fill</valign>
|
||||
<stretch>true</stretch>
|
||||
<pref-width>600</pref-width>
|
||||
<pref-height>250</pref-height>
|
||||
<padding>6</padding>
|
||||
<slider>20</slider>
|
||||
<editable>falsee</editable>
|
||||
<wrap>false</wrap>
|
||||
<font>
|
||||
<name>FIXED_8x13</name>
|
||||
</font>
|
||||
<property>/sim/gui/dialogs/doc-browser/edit</property>
|
||||
</textbox>
|
||||
</group>
|
||||
|
||||
<nasal>
|
||||
<open>
|
||||
var self = cmdarg();
|
||||
var dlg = props.globals.getNode("/sim/gui/dialogs/doc-browser", 1);
|
||||
var edit = dlg.getNode("edit", 1);
|
||||
if( !contains(globals, "__doc_browser") )
|
||||
globals["__doc_browser"] = {};
|
||||
|
||||
var path = getprop("/sim/fg-root") ~ "/Docs/";
|
||||
# hard coded list of file names, because not all files are plain text - not even the README* files
|
||||
# TODO: it would probably make sense to sort these files (README, introduction, properties etc)
|
||||
var doc_files = [
|
||||
"README",
|
||||
"README.introduction",
|
||||
"README.fgjs",
|
||||
"README.xmlsyntax",
|
||||
"README.multiscreen",
|
||||
"README.properties",
|
||||
"README.IO",
|
||||
"README.logging",
|
||||
"README.protocol",
|
||||
"README.scenery",
|
||||
"README.materials",
|
||||
"README.yasim",
|
||||
"README.JSBsim",
|
||||
"README.submodels",
|
||||
"README.3DClouds",
|
||||
"README.flightrecorder",
|
||||
"README.jsclient",
|
||||
"README.multiplayer",
|
||||
"README.tutorials",
|
||||
"README.conditions",
|
||||
"README.commands",
|
||||
"README.digitalfilters",
|
||||
"README.airspeed-indicator",
|
||||
"README.hud",
|
||||
# "README.xmlhud", deprecated?
|
||||
"README.gui",
|
||||
"README.layout",
|
||||
"README.osgtext",
|
||||
"README.wildfire",
|
||||
"README.electrical",
|
||||
"README.effects",
|
||||
"README.xmlparticles",
|
||||
"README.sound",
|
||||
"README.xmlsound",
|
||||
"README.xmlpanel",
|
||||
"README.minipanel"
|
||||
];
|
||||
var filename_list = self.getNode("group[1]/list");
|
||||
var n=0;
|
||||
# add the filenames to the list box
|
||||
foreach(var file; doc_files)
|
||||
{
|
||||
filename_list.getChild("value",n,1).setValue( file );
|
||||
n+=1;
|
||||
}
|
||||
var filename_property = "/sim/gui/dialogs/doc-browser/filename";
|
||||
var update = func {
|
||||
var file = getprop(filename_property);
|
||||
var doc_file = path ~ file;
|
||||
setprop("/sim/gui/dialogs/doc-browser/edit", io.readfile(doc_file));
|
||||
}
|
||||
|
||||
var listener = setlistener(filename_property, update);
|
||||
setprop("/sim/gui/dialogs/doc-browser/filename", "README.introduction");
|
||||
</open>
|
||||
<close>removelistener(listener);</close>
|
||||
</nasal>
|
||||
</PropertyList>
|
|
@ -216,6 +216,42 @@
|
|||
<col>3</col>
|
||||
</text>
|
||||
|
||||
|
||||
<text>
|
||||
<label>Vegetation</label>
|
||||
<halign>left</halign>
|
||||
<row>5</row>
|
||||
<col>0</col>
|
||||
</text>
|
||||
|
||||
<text>
|
||||
<label>none</label>
|
||||
<halign>right</halign>
|
||||
<row>5</row>
|
||||
<col>1</col>
|
||||
</text>
|
||||
|
||||
<slider>
|
||||
<name>lichen-level</name>
|
||||
<row>5</row>
|
||||
<col>2</col>
|
||||
<min>0.0</min>
|
||||
<max>0.7</max>
|
||||
<live>true</live>
|
||||
<property>/environment/surface/lichen-cover-factor</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
<object-name>lichen-level</object-name>
|
||||
</binding>
|
||||
</slider>
|
||||
|
||||
<text>
|
||||
<label>mossy</label>
|
||||
<halign>left</halign>
|
||||
<row>5</row>
|
||||
<col>3</col>
|
||||
</text>
|
||||
|
||||
</group>
|
||||
|
||||
<hrule/>
|
||||
|
|
744
gui/dialogs/images/ndb_symbol.svg
Normal file
744
gui/dialogs/images/ndb_symbol.svg
Normal file
|
@ -0,0 +1,744 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://web.resource.org/cc/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="50"
|
||||
height="50"
|
||||
id="svg2"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.45.1"
|
||||
sodipodi:docbase="C:\Documents and Settings\JJB\My Documents"
|
||||
sodipodi:docname="NDB Symbol.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.0">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="3.1"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="71.027314"
|
||||
inkscape:cy="17.078887"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g3816"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="1404"
|
||||
inkscape:window-height="874"
|
||||
inkscape:window-x="28"
|
||||
inkscape:window-y="0"
|
||||
width="50px"
|
||||
height="50px"
|
||||
showgrid="false"
|
||||
inkscape:grid-points="true"
|
||||
gridspacingx="5px"
|
||||
gridspacingy="5px"
|
||||
inkscape:guide-points="false" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g2842"
|
||||
transform="matrix(0.9655323,-0.2602834,0.2602834,0.9655323,-98.55675,-17.522102)"
|
||||
inkscape:transform-center-y="-186.61497"
|
||||
inkscape:transform-center-x="50.854555" />
|
||||
<g
|
||||
id="g4183"
|
||||
transform="translate(6.3118628,-54.869792)">
|
||||
<g
|
||||
transform="translate(-56.311844,-45.130208)"
|
||||
id="g3816">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3586"
|
||||
sodipodi:cx="75"
|
||||
sodipodi:cy="125"
|
||||
sodipodi:rx="5"
|
||||
sodipodi:ry="5"
|
||||
d="M 80 125 A 5 5 0 1 1 70,125 A 5 5 0 1 1 80 125 z" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3588"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,98.125)" />
|
||||
<g
|
||||
id="g3652">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,88.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3648"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,108.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3650"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3656"
|
||||
transform="matrix(0.8660254,-0.5,0.5,0.8660254,-52.451905,54.246825)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3658"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,88.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3660"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,108.125)" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.5,-0.8660254,0.8660254,0.5,-70.753175,127.45191)"
|
||||
id="g3662">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,88.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3664"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,108.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3666"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3668"
|
||||
transform="matrix(0,-1,1,0,-50,200)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3670"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,88.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3672"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,108.125)" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.5,-0.8660254,0.8660254,-0.5,4.2468245,252.45191)"
|
||||
id="g3674">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,88.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3676"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,108.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3678"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3680"
|
||||
transform="matrix(-0.8660254,-0.5,0.5,-0.8660254,77.451905,270.75318)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3682"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,88.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3684"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,108.125)" />
|
||||
</g>
|
||||
<g
|
||||
id="g3690"
|
||||
transform="matrix(0.9063078,-0.4226182,0.4226182,0.9063078,-45.800367,43.407896)">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,83.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3686"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,113.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3688"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.7071067,-0.7071068,0.7071068,0.7071067,-66.421357,89.644658)"
|
||||
id="g3694">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3696"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,83.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3698"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,113.125)" />
|
||||
</g>
|
||||
<g
|
||||
id="g3700"
|
||||
transform="matrix(0.4226183,-0.9063078,0.9063078,0.4226183,-69.984843,140.1458)">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,83.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3702"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,113.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3704"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(8.715577e-2,-0.9961946,0.9961946,8.715577e-2,-56.061019,188.82012)"
|
||||
id="g3706">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3708"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,83.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3710"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,113.125)" />
|
||||
</g>
|
||||
<g
|
||||
id="g3712"
|
||||
transform="matrix(-0.258819,-0.9659258,0.9659258,-0.258819,-26.329304,229.7968)">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,83.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3714"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,113.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3716"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.5735763,-0.819152,0.819152,-0.5735763,15.624218,258.13344)"
|
||||
id="g3718">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3720"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,83.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3722"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,113.125)" />
|
||||
</g>
|
||||
<g
|
||||
id="g3724"
|
||||
transform="matrix(-0.8191519,-0.5735764,0.5735764,-0.8191519,64.739336,270.41222)">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,83.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3726"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,113.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3728"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.9659257,-0.2588191,0.2588191,-0.9659257,115.09204,265.15215)"
|
||||
id="g3730">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3732"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,83.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3734"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,113.125)" />
|
||||
</g>
|
||||
<g
|
||||
id="g3736"
|
||||
transform="matrix(-0.9961946,8.715564e-2,-8.715564e-2,-0.9961946,160.60905,242.98766)">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,83.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3738"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,113.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3740"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3746">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3742"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3744"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3750"
|
||||
transform="matrix(0.9659258,-0.258819,0.258819,0.9659258,-29.796818,23.6707)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3752"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3754"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.8660254,-0.4999999,0.4999999,0.8660254,-52.451906,54.246822)"
|
||||
id="g3756">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3758"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3760"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3762"
|
||||
transform="matrix(0.7071068,-0.7071067,0.7071067,0.7071068,-66.421359,89.644655)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3764"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3766"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.5,-0.8660253,0.8660253,0.5,-70.753181,127.4519)"
|
||||
id="g3768">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3770"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3772"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3774"
|
||||
transform="matrix(0.2588191,-0.9659257,0.9659257,0.2588191,-65.152165,165.09205)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3776"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3778"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(8.5712909e-8,-0.9999999,0.9999999,8.5712909e-8,-50.000013,199.99999)"
|
||||
id="g3780">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3782"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3784"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3786"
|
||||
transform="matrix(-0.2588189,-0.9659258,0.9659258,-0.2588189,-26.329318,229.79681)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3788"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3790"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.4999999,-0.8660254,0.8660254,-0.4999999,4.2468015,252.4519)"
|
||||
id="g3792">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3794"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3796"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3798"
|
||||
transform="matrix(-0.7071067,-0.7071068,0.7071068,-0.7071067,39.644635,266.42135)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3800"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3802"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.8660253,-0.5,0.5,-0.8660253,77.451877,270.75317)"
|
||||
id="g3804">
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3806"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
sodipodi:ry="2.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:cx="47.5"
|
||||
id="path3808"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3810"
|
||||
transform="matrix(-0.9659257,-0.2588191,0.2588191,-0.9659257,115.09202,265.15215)">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3812"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,118.125)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path3814"
|
||||
sodipodi:cx="47.5"
|
||||
sodipodi:cy="107.5"
|
||||
sodipodi:rx="2.5"
|
||||
sodipodi:ry="2.5"
|
||||
d="M 50 107.5 A 2.5 2.5 0 1 1 45,107.5 A 2.5 2.5 0 1 1 50 107.5 z"
|
||||
transform="matrix(0.25,0,0,0.25,63.125,78.125)" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 35 KiB |
|
@ -13,7 +13,7 @@
|
|||
</empty>
|
||||
|
||||
<text>
|
||||
<label>Rendering options</label>
|
||||
<label>Rendering Options</label>
|
||||
</text>
|
||||
|
||||
<empty>
|
||||
|
@ -193,6 +193,16 @@
|
|||
|
||||
-->
|
||||
|
||||
<checkbox>
|
||||
<halign>left</halign>
|
||||
<label>Compensate field of view for wider screens</label>
|
||||
<property>sim/current-view/field-of-view-compensation</property>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>view.screenWidthCompens(1)</script>
|
||||
</binding>
|
||||
</checkbox>
|
||||
|
||||
<group>
|
||||
<layout>hbox</layout>
|
||||
<text>
|
||||
|
@ -206,11 +216,46 @@
|
|||
|
||||
<group>
|
||||
<layout>table</layout>
|
||||
|
||||
<checkbox>
|
||||
|
||||
<text>
|
||||
<row>0</row>
|
||||
<col>0</col>
|
||||
<halign>left</halign>
|
||||
<label>Texture set</label>
|
||||
</text>
|
||||
|
||||
<combo>
|
||||
<row>0</row>
|
||||
<col>1</col>
|
||||
<colspan>3</colspan>
|
||||
<name>texture-set</name>
|
||||
<halign>fill</halign>
|
||||
<stretch>true</stretch>
|
||||
<pref-width>150</pref-width>
|
||||
<property>sim/gui/dialogs/rendering/texture-set</property>
|
||||
<value>Region-specific</value>
|
||||
<value>Global</value>
|
||||
<value>DDS</value>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
<object-name>texture-set</object-name>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
var file = materials[getprop("/sim/gui/dialogs/rendering/texture-set")];
|
||||
setprop("/sim/rendering/materials-file", file);
|
||||
</script>
|
||||
</binding>
|
||||
<binding>
|
||||
<command>reload-materials</command>
|
||||
</binding>
|
||||
</combo>
|
||||
|
||||
<checkbox>
|
||||
<row>1</row>
|
||||
<col>0</col>
|
||||
<halign>left</halign>
|
||||
<label>Animated jetways</label>
|
||||
<name>jetways</name>
|
||||
<property>/nasal/jetways/enabled</property>
|
||||
|
@ -221,7 +266,7 @@
|
|||
</checkbox>
|
||||
|
||||
<checkbox>
|
||||
<row>1</row>
|
||||
<row>2</row>
|
||||
<col>0</col>
|
||||
<halign>left</halign>
|
||||
<label>Random buildings</label>
|
||||
|
@ -234,7 +279,7 @@
|
|||
</checkbox>
|
||||
|
||||
<text>
|
||||
<row>1</row>
|
||||
<row>2</row>
|
||||
<col>1</col>
|
||||
<colspan>3</colspan>
|
||||
<color>
|
||||
|
@ -246,7 +291,7 @@
|
|||
</text>
|
||||
|
||||
<checkbox>
|
||||
<row>2</row>
|
||||
<row>3</row>
|
||||
<col>0</col>
|
||||
<halign>left</halign>
|
||||
<label>Random objects</label>
|
||||
|
@ -259,7 +304,7 @@
|
|||
</checkbox>
|
||||
|
||||
<checkbox>
|
||||
<row>3</row>
|
||||
<row>4</row>
|
||||
<col>0</col>
|
||||
<halign>left</halign>
|
||||
<label>Random vegetation</label>
|
||||
|
@ -271,7 +316,7 @@
|
|||
</binding>
|
||||
</checkbox>
|
||||
<text>
|
||||
<row>3</row>
|
||||
<row>4</row>
|
||||
<col>1</col>
|
||||
<label>density</label>
|
||||
<enable>
|
||||
|
@ -279,7 +324,7 @@
|
|||
</enable>
|
||||
</text>
|
||||
<slider>
|
||||
<row>3</row>
|
||||
<row>4</row>
|
||||
<col>2</col>
|
||||
<name>vegetation-density</name>
|
||||
<min>0</min>
|
||||
|
@ -292,7 +337,7 @@
|
|||
</binding>
|
||||
</slider>
|
||||
<text>
|
||||
<row>3</row>
|
||||
<row>4</row>
|
||||
<col>3</col>
|
||||
<label>12345678</label>
|
||||
<format>%.1f</format>
|
||||
|
@ -699,9 +744,22 @@
|
|||
|
||||
<nasal>
|
||||
<open>
|
||||
|
||||
var materials = { "Region-specific" : "Materials/regions/materials.xml",
|
||||
"Global" : "Materials/default/materials.xml",
|
||||
"DDS" : "Materials/dds/materials.xml" };
|
||||
|
||||
|
||||
gui.enable_widgets(cmdarg(), "shadows-debug", getprop("/sim/gui/devel-widgets"));
|
||||
props.globals.getNode("/sim/rendering/shaders/quality-level", 1).setAttribute("userarchive", 0);
|
||||
setprop("/sim/gui/frame-rate-throttled", (getprop("/sim/frame-rate-throttle-hz") > 0));
|
||||
|
||||
var matfile = getprop("/sim/rendering/materials-file");
|
||||
foreach (var name; keys(materials)) {
|
||||
if (matfile == materials[name]) {
|
||||
setprop("/sim/gui/dialogs/rendering/texture-set", name);
|
||||
}
|
||||
}
|
||||
</open>
|
||||
</nasal>
|
||||
</PropertyList>
|
||||
|
|
|
@ -38,7 +38,9 @@ command interface /autopilot/route-manager/input:
|
|||
}
|
||||
|
||||
var clear = func {
|
||||
#cmd.setValue("@clear");
|
||||
# deactive first, see http://https://code.google.com/p/flightgear-bugs/issues/detail?id=885
|
||||
fgcommand("activate-flightplan", props.Node.new({"activate": 0}));
|
||||
|
||||
flightplan().cleanPlan();
|
||||
selection.setIntValue(-1);
|
||||
}
|
||||
|
@ -60,13 +62,10 @@ command interface /autopilot/route-manager/input:
|
|||
}
|
||||
|
||||
var remove = func {
|
||||
#cmd.setValue("@delete" ~ sel_index());
|
||||
flightplan().deleteWP(sel_index());
|
||||
}
|
||||
|
||||
var route = func {
|
||||
#cmd.setValue("@route" ~ sel_index());
|
||||
|
||||
var route = func {
|
||||
var fp = flightplan();
|
||||
var from = fp.getWP(sel_index() - 1);
|
||||
var to = fp.getWP(sel_index());
|
||||
|
@ -81,7 +80,6 @@ command interface /autopilot/route-manager/input:
|
|||
}
|
||||
|
||||
var jump_to = func {
|
||||
#cmd.setValue("@jump" ~ sel_index());
|
||||
flightplan().current = sel_index();
|
||||
}
|
||||
|
||||
|
@ -101,7 +99,7 @@ command interface /autopilot/route-manager/input:
|
|||
var save_selector = gui.FileSelector.new(save_route, "Save flight-plan", "Save");
|
||||
|
||||
var activate_fp = func {
|
||||
cmd.setValue("@activate");
|
||||
fgcommand("activate-flightplan", props.Node.new({"activate": 1}));
|
||||
}
|
||||
|
||||
var departureRunways = dlg.getNode("departure-runways", 1);
|
||||
|
|
|
@ -356,6 +356,7 @@
|
|||
if (cmp(current, new) != 0) {
|
||||
setprop("sim/sound/devices/name", new);
|
||||
setprop("sim/sound/device-name", new);
|
||||
fgcommand("reinit", props.Node.new({ "subsystem" : "sound" }));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@
|
|||
setprop("/nasal/local_weather/enabled", "true");
|
||||
|
||||
# Re-initialize local weather.
|
||||
local_weather.set_tile();
|
||||
settimer( func {local_weather.set_tile();}, 0.2);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
<command>dialog-show</command>
|
||||
<dialog-name>sound-dialog</dialog-name>
|
||||
</binding>
|
||||
<enabled>false</enabled>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
|
@ -703,6 +704,14 @@
|
|||
</binding>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<name>doc-browser</name>
|
||||
<binding>
|
||||
<command>dialog-show</command>
|
||||
<dialog-name>doc-browser</dialog-name>
|
||||
</binding>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<key>?</key>
|
||||
<name>aircraft-keys</name>
|
||||
|
|
|
@ -153,7 +153,7 @@ Started September 2000 by David Megginson, david@megginson.com
|
|||
<mie type="float" userarchive="y">0.003</mie>
|
||||
<rayleigh type="float" userarchive="y">0.0003</rayleigh>
|
||||
<dome-density type="float" userarchive="y">0.5</dome-density>
|
||||
<!-- multithreading-mode>AutomaticSelection</multithreading-mode -->
|
||||
<multithreading-mode>AutomaticSelection</multithreading-mode>
|
||||
<!--
|
||||
Uncomment the above element to select OSG multi-threading mode.
|
||||
This may improve performance on multi-core, multi-CPU
|
||||
|
@ -346,6 +346,7 @@ Started September 2000 by David Megginson, david@megginson.com
|
|||
<speed-up type="double">1.0</speed-up>
|
||||
<current-view>
|
||||
<field-of-view type="double">55.0</field-of-view>
|
||||
<field-of-view-compensation type="bool" userarchive="y">false</field-of-view-compensation>
|
||||
<aspect-ratio-multiplier type="double">1.0</aspect-ratio-multiplier>
|
||||
<dynamic-view type="bool" userarchive="y">false</dynamic-view>
|
||||
</current-view>
|
||||
|
|
Loading…
Add table
Reference in a new issue