1
0
Fork 0

Marker-pins FGData changes

From Tobias Dammers
This commit is contained in:
James Turner 2022-01-27 12:11:24 +00:00
parent 1bd128bb63
commit 2d17217a01
7 changed files with 405 additions and 2 deletions

32
Effects/marker-pin.eff Normal file
View 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>

View file

@ -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);

View file

@ -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
View 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
View 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
View 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;
}

View file

@ -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/>