Marker-pins FGData changes
From Tobias Dammers
This commit is contained in:
parent
1bd128bb63
commit
2d17217a01
7 changed files with 405 additions and 2 deletions
32
Effects/marker-pin.eff
Normal file
32
Effects/marker-pin.eff
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PropertyList>
|
||||
<name>Effects/marker-pin</name>
|
||||
<parameters>
|
||||
</parameters>
|
||||
|
||||
<technique>
|
||||
<predicate>
|
||||
<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>
|
||||
</predicate>
|
||||
<pass>
|
||||
<cull-face>back</cull-face>
|
||||
<!-- <rendering-hint>transparent</rendering-hint> -->
|
||||
<program>
|
||||
<vertex-shader>Shaders/marker-pin.vert</vertex-shader>
|
||||
<fragment-shader>Shaders/marker-pin.frag</fragment-shader>
|
||||
</program>
|
||||
</pass>
|
||||
</technique>
|
||||
|
||||
</PropertyList>
|
|
@ -330,11 +330,20 @@ var tile_path = func(lat, lon) {
|
|||
|
||||
|
||||
var put_model = func(path, c, arg...) {
|
||||
call(_put_model, [path] ~ (isa(c, Coord) ? c.latlon() : [c]) ~ arg);
|
||||
call(_put_model, [path, nil] ~ (isa(c, Coord) ? c.latlon() : [c]) ~ arg);
|
||||
}
|
||||
|
||||
var put_marker = func(label, c, arg...) {
|
||||
if (isa(c, Coord)) {
|
||||
call(_put_marker, [label] ~ c.latlon() ~ arg);
|
||||
}
|
||||
else {
|
||||
call(_put_marker, [label, c] ~ arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var _put_model = func(path, lat, lon, elev_m = nil, hdg = 0, pitch = 0, roll = 0) {
|
||||
var _put_model = func(path, label, lat, lon, elev_m = nil, hdg = 0, pitch = 0, roll = 0) {
|
||||
if (elev_m == nil)
|
||||
elev_m = elevation(lat, lon);
|
||||
if (elev_m == nil)
|
||||
|
@ -346,6 +355,42 @@ var _put_model = func(path, lat, lon, elev_m = nil, hdg = 0, pitch = 0, roll = 0
|
|||
return props.globals.getNode(n.getNode("property").getValue());
|
||||
}
|
||||
|
||||
var _put_marker = func(label, lat, lon, elev = nil, color = nil, text_height_m = 1, pin_height_m = 1000, pin_tip_height_m = 0) {
|
||||
params = {
|
||||
"internal-model": "marker",
|
||||
"heading-deg": 0, "pitch-deg": 0, "roll-deg": 0,
|
||||
"marker": {
|
||||
"text": label,
|
||||
"color": color,
|
||||
"size": text_height_m,
|
||||
"height": pin_height_m,
|
||||
"tip-height": pin_tip_height_m,
|
||||
},
|
||||
};
|
||||
if (isnum(lat)) {
|
||||
params['latitude-deg'] = lat;
|
||||
}
|
||||
elsif (isscalar(lat)) {
|
||||
params['latitude-deg-prop'] = lat;
|
||||
}
|
||||
if (isnum(lon)) {
|
||||
params['longitude-deg'] = lon;
|
||||
}
|
||||
elsif (isscalar(lon)) {
|
||||
params['longitude-deg-prop'] = lon;
|
||||
}
|
||||
if (isnum(elev)) {
|
||||
params['elevation-ft'] = elev;
|
||||
}
|
||||
elsif (isscalar(elev)) {
|
||||
params['elevation-ft-prop'] = elev;
|
||||
}
|
||||
if (color == nil)
|
||||
color = [1, 1, 1];
|
||||
fgcommand("add-model", var n = props.Node.new(params));
|
||||
return props.globals.getNode(n.getNode("property").getValue());
|
||||
}
|
||||
|
||||
|
||||
var elevation = func(lat, lon, maxalt = 10000) {
|
||||
var d = geodinfo(lat, lon, maxalt);
|
||||
|
|
|
@ -56,4 +56,5 @@ geo.nas <- view.nas
|
|||
<file>multiplayer.nas</file>
|
||||
<file>geo.nas</file>
|
||||
<file>view.nas</file>
|
||||
<file>markerpins.nas</file>
|
||||
</PropertyList>
|
||||
|
|
215
Nasal/markerpins.nas
Normal file
215
Nasal/markerpins.nas
Normal file
|
@ -0,0 +1,215 @@
|
|||
var pin_update_timer = nil;
|
||||
|
||||
var navPins = {};
|
||||
var poiPins = {};
|
||||
var trafficPins = {};
|
||||
var trafficAddListener = nil;
|
||||
var trafficRemoveListener = nil;
|
||||
|
||||
var enabled = {
|
||||
master: 0,
|
||||
airports: 0,
|
||||
navaids: 0,
|
||||
fixes: 0,
|
||||
pois: 0,
|
||||
traffic: 0,
|
||||
};
|
||||
|
||||
var update_pins = func () {
|
||||
var navs = [];
|
||||
if (enabled.master) {
|
||||
if (enabled.airports) {
|
||||
airports = findAirportsWithinRange(50);
|
||||
navs = navs ~ airports;
|
||||
}
|
||||
if (enabled.navaids) {
|
||||
navaids = findNavaidsWithinRange(50, "vor") ~
|
||||
findNavaidsWithinRange(50, "ndb") ~
|
||||
findNavaidsWithinRange(20, "ils") ~
|
||||
findNavaidsWithinRange(20, "loc");
|
||||
navs = navs ~ navaids;
|
||||
}
|
||||
if (enabled.fixes) {
|
||||
# navaids = findNavaidsWithinRange(50, "fix");
|
||||
# navs = navs ~ navaids;
|
||||
}
|
||||
if (enabled.pois) {
|
||||
navaids = findNavaidsWithinRange(50, "city") ~
|
||||
findNavaidsWithinRange(15, "town") ~
|
||||
findNavaidsWithinRange(5, "village");
|
||||
navs = navs ~ navaids;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var k; keys(navPins)) {
|
||||
navPins[k].alive = 0;
|
||||
}
|
||||
foreach (var nav; navs) {
|
||||
var pin = navPins[nav.id];
|
||||
if (pin == nil) {
|
||||
var color = [1, 1, 1];
|
||||
var height = 600;
|
||||
var fsize = 128;
|
||||
var elevation = nav.elevation;
|
||||
if (elevation == nil or elevation == 0) {
|
||||
elevation = geo.elevation(nav.lat, nav.lon);
|
||||
}
|
||||
if (elevation == nil) {
|
||||
continue;
|
||||
}
|
||||
elevation = elevation * M2FT;
|
||||
if (ghosttype(nav) == "airport") {
|
||||
color = [1, 0, 0];
|
||||
fsize = 256;
|
||||
height = 1200;
|
||||
}
|
||||
else {
|
||||
if (nav.type == "VOR") {
|
||||
color = [0, 0.5, 1];
|
||||
fsize = 160;
|
||||
height = 900;
|
||||
}
|
||||
elsif (nav.type == "NDB") {
|
||||
color = [0.5, 0.25, 0];
|
||||
fsize = 128;
|
||||
height = 700;
|
||||
}
|
||||
elsif (nav.type == "LOC" or nav.type == "ILS") {
|
||||
color = [0, 1, 1];
|
||||
fsize = 32;
|
||||
height = 50;
|
||||
}
|
||||
elsif (nav.type == "FIX") {
|
||||
color = [1, 1, 0];
|
||||
fsize = 64;
|
||||
height = 900;
|
||||
}
|
||||
elsif (nav.type == "city") {
|
||||
color = [1, 1, 1];
|
||||
fsize = 256;
|
||||
height = 600;
|
||||
}
|
||||
elsif (nav.type == "town") {
|
||||
color = [1, 1, 1];
|
||||
fsize = 128;
|
||||
height = 300;
|
||||
}
|
||||
elsif (nav.type == "village") {
|
||||
color = [1, 1, 1];
|
||||
fsize = 64;
|
||||
height = 150;
|
||||
}
|
||||
}
|
||||
pin = {
|
||||
marker: geo.put_marker(nav.id, nav.lat, nav.lon, elevation, color, fsize, height),
|
||||
};
|
||||
navPins[nav.id] = pin;
|
||||
}
|
||||
navPins[nav.id].alive = 1;
|
||||
}
|
||||
foreach (var k; keys(navPins)) {
|
||||
if (!navPins[k].alive) {
|
||||
navPins[k].marker.remove();
|
||||
delete(navPins, k);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var toggleTrafficPins = func (node) {
|
||||
if (node.getBoolValue()) {
|
||||
# turn on
|
||||
print("Traffic pins on");
|
||||
var modelsNode = props.getNode('/ai/models');
|
||||
var nodes = modelsNode.getChildren('multiplayer') ~
|
||||
modelsNode.getChildren('swift') ~
|
||||
modelsNode.getChildren('aircraft');
|
||||
foreach (var k; keys(trafficPins)) {
|
||||
trafficPins[k].alive = 0;
|
||||
}
|
||||
var addTraffic = func (node, retry=3) {
|
||||
var nodeID = node.getName() ~ ':' ~ node.getIndex();
|
||||
var callsign = node.getValue('callsign');
|
||||
printf("Adding traffic: %s [%s]", nodeID, node.getValue('callsign'));
|
||||
if (callsign == nil) {
|
||||
if (retry > 0) {
|
||||
# try again in 1 second
|
||||
settimer(func { addTraffic(node, retry-1); }, 1);
|
||||
}
|
||||
else {
|
||||
printf("Giving up on %s", nodeID);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var pin = trafficPins[nodeID];
|
||||
if (pin == nil) {
|
||||
var elev_prop = node.getPath() ~ '/position/altitude-ft';
|
||||
var lat_prop = node.getPath() ~ '/position/latitude-deg';
|
||||
var lon_prop = node.getPath() ~ '/position/longitude-deg';
|
||||
pin = {
|
||||
marker: geo.put_marker(callsign, lat_prop, lon_prop, elev_prop, [1,1,0], 10, 15, 5),
|
||||
};
|
||||
trafficPins[nodeID] = pin;
|
||||
}
|
||||
trafficPins[nodeID].alive = 1;
|
||||
}
|
||||
};
|
||||
foreach (var node; nodes) {
|
||||
if (node.getValue('valid')) {
|
||||
addTraffic(node);
|
||||
}
|
||||
}
|
||||
trafficRemoveListener = setlistener('/ai/models/model-removed', func(n) {
|
||||
var path = n.getValue();
|
||||
var node = props.getNode(path);
|
||||
var nodeID = node.getName() ~ ':' ~ node.getIndex();
|
||||
if (trafficPins[nodeID] != nil) {
|
||||
trafficPins[nodeID].marker.remove();
|
||||
delete(trafficPins, nodeID);
|
||||
}
|
||||
});
|
||||
trafficAddListener = setlistener('/ai/models/model-added', func (n) {
|
||||
var path = n.getValue();
|
||||
var node = props.getNode(path);
|
||||
addTraffic(node);
|
||||
});
|
||||
foreach (var k; keys(trafficPins)) {
|
||||
if (!trafficPins[k].alive) {
|
||||
trafficPins[l].marker.remove();
|
||||
delete(trafficPins, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
# turn off
|
||||
print("Traffic pins off");
|
||||
if (trafficAddListener != nil) removelistener(trafficAddListener);
|
||||
if (trafficRemoveListener != nil) removelistener(trafficRemoveListener);
|
||||
foreach (var k; keys(trafficPins)) {
|
||||
trafficPins[k].marker.remove();
|
||||
}
|
||||
trafficPins = {};
|
||||
}
|
||||
};
|
||||
|
||||
var fdm_init_listener = setlistener("/sim/signals/fdm-initialized", func {
|
||||
removelistener(fdm_init_listener); # uninstall, so we are only called once
|
||||
|
||||
foreach (var k; ['master', 'airports', 'navaids', 'fixes', 'pois', 'traffic']) {
|
||||
var path = '/sim/marker-pins/' ~ k;
|
||||
var node = props.getNode(path);
|
||||
if (node == nil) {
|
||||
node = props.getNode(path, 1);
|
||||
node.setBoolValue(0);
|
||||
node.setAttribute('userarchive', 'y');
|
||||
}
|
||||
if (k == 'traffic') {
|
||||
setlistener(path, toggleTrafficPins, 1, 0);
|
||||
}
|
||||
else {
|
||||
setlistener(path, (func (key) { return func (p) { enabled[key] = p.getBoolValue(); }; })(k), 1, 0);
|
||||
}
|
||||
}
|
||||
var timer = maketimer(1, update_pins);
|
||||
|
||||
timer.start();
|
||||
});
|
21
Shaders/marker-pin.frag
Normal file
21
Shaders/marker-pin.frag
Normal file
|
@ -0,0 +1,21 @@
|
|||
// -*-C++-*-
|
||||
|
||||
#version 120
|
||||
|
||||
uniform sampler2D texture;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = gl_Color;
|
||||
// vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
vec4 texel;
|
||||
vec4 fragColor;
|
||||
|
||||
texel = texture2D(texture, gl_TexCoord[0].st);
|
||||
|
||||
fragColor.rgb = color.rgb;
|
||||
fragColor.a = texel.a * color.a;
|
||||
|
||||
gl_FragColor = fragColor;
|
||||
}
|
||||
|
18
Shaders/marker-pin.vert
Normal file
18
Shaders/marker-pin.vert
Normal file
|
@ -0,0 +1,18 @@
|
|||
// -*-C++-*-
|
||||
|
||||
// Shader that uses OpenGL state values to do per-pixel lighting
|
||||
//
|
||||
// The only light used is gl_LightSource[0], which is assumed to be
|
||||
// directional.
|
||||
//
|
||||
// Diffuse colors come from the gl_Color, ambient from the material. This is
|
||||
// equivalent to osg::Material::DIFFUSE.
|
||||
#version 120
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
gl_FrontColor = gl_Color;
|
||||
gl_BackColor = gl_Color;
|
||||
}
|
|
@ -305,6 +305,77 @@
|
|||
|
||||
</group>
|
||||
|
||||
<vrule/>
|
||||
|
||||
<group>
|
||||
<layout>vbox</layout>
|
||||
<halign>center</halign>
|
||||
<valign>top</valign>
|
||||
|
||||
<text>
|
||||
<label>Marker Pins</label>
|
||||
</text>
|
||||
|
||||
<checkbox>
|
||||
<halign>left</halign>
|
||||
<label>Show</label>
|
||||
<property>/sim/marker-pins/master</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
</binding>
|
||||
</checkbox>
|
||||
|
||||
<hrule/>
|
||||
|
||||
<checkbox>
|
||||
<halign>left</halign>
|
||||
<label>Airports</label>
|
||||
<property>/sim/marker-pins/airports</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
</binding>
|
||||
</checkbox>
|
||||
|
||||
<checkbox>
|
||||
<halign>left</halign>
|
||||
<label>Navaids</label>
|
||||
<property>/sim/marker-pins/navaids</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
</binding>
|
||||
</checkbox>
|
||||
|
||||
<checkbox>
|
||||
<halign>left</halign>
|
||||
<label>Fixes</label>
|
||||
<property>/sim/marker-pins/fixes</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
</binding>
|
||||
</checkbox>
|
||||
|
||||
<checkbox>
|
||||
<halign>left</halign>
|
||||
<label>POI</label>
|
||||
<property>/sim/marker-pins/pois</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
</binding>
|
||||
</checkbox>
|
||||
|
||||
<hrule/>
|
||||
|
||||
<checkbox>
|
||||
<halign>left</halign>
|
||||
<label>Traffic</label>
|
||||
<property>/sim/marker-pins/traffic</property>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
</binding>
|
||||
</checkbox>
|
||||
|
||||
</group>
|
||||
|
||||
</group>
|
||||
|
||||
<hrule/>
|
||||
|
|
Loading…
Add table
Reference in a new issue