Board index FlightGear Development Canvas

Get objects to show up on Map/Radar

Canvas is FlightGear's new fully scriptable 2D drawing system that will allow you to easily create new instruments, HUDs and even GUI dialogs and custom GUI widgets, without having to write C++ code and without having to rebuild FlightGear.

Re: Get objects to show up on Map/Radar

Postby RevHardt » Tue Mar 24, 2015 3:43 am

Yes, that's what I'm saying. The AA layer should show up like it used to in this post from this very thread.

  • Property /sim/gui/dialogs/map-canvas/draw-AA = '1' (string), which, although it is not a bool like for the other layers, toggles the state of the corresponding Map (Canvas) checkbox just fine.
  • Correct me if I'm wrong, but by unchecking all other layers and toggling the AA layer checkbox (to no avail), z-indexing issues can be ruled out?
  • Adding the AA layer to the ones already in the demo code gives expected results - everything overlaid like it should be.
  • Printlining the file loading section (near the end of MapStructure.nas) confirms that both AA.lcontroller and AA.symbol are being loaded.
The constructor in AA.lcontroller fires only when the demo code creates the makeshift Canvas Dialog:
Code: Select all
var new = func(layer)
          {
            print("!!! AA ctor !!!");
            ...

Toggling the checkbox in Map (Canvas) does not execute it. For some reason, the checkbox:
Code: Select all
<checkbox>
  <label>Anti-aircraft</label>
  <pref-width>100</pref-width>
  <property>/sim/gui/dialogs/map-canvas/draw-AA</property>
  <live>true</live>
  <binding>
    <command>dialog-apply</command>
  </binding>
  <binding>
    <command>property-toggle</command>
  </binding>
</checkbox>

... in map-canvas.xml seems to remain unregistered as the actuator of the AA layer. Am I missing a step to that effect somewhere?
Take a look to the sky just before you die; it's the last time you will.
RevHardt
 
Posts: 31
Joined: Tue Jun 10, 2014 3:59 pm
Version: 3.4.0
OS: Win 7 Pro SP1 x64

Re: Get objects to show up on Map/Radar

Postby Hooray » Tue Mar 24, 2015 3:22 pm

This is hard/impossible to troubleshoot without looking at all your changes - however, just a guess: could you have skipped the step where the toggle property needs to be hooked up to the layer/map controller ? I mean, did you adapt/augment the corresponding Nasal section in the map-canvas.xml dialog accordingly ?

http://sourceforge.net/p/flightgear/fgd ... s.xml#l441

Otherwise, there's the hard-coded assumption that the toggle property is named accordingly.

So I would add some printlog/print statements there to see what it is doing.

Admittedly, this is a bit messy - but we're hoping to phase out the map-canvaas.xml dialog anyway - and use the native Canvas approach instead (as per the demo code you're using for testing).
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Get objects to show up on Map/Radar

Postby RevHardt » Tue Mar 24, 2015 4:08 pm

Found what I was missing, after all:
Code: Select all
foreach(var type; [r('AA'),r('TFC',0),r('APT'), ...
                   ^^^^^^^^
in the vector of layer types in this line. Thanks, Hooray! It had to be a step present in the demo code, which I wasn't taking care of.

Admittedly, this is a bit messy - but we're hoping to phase out the map-canvaas.xml dialog anyway - and use the native Canvas approach instead (as per the demo code you're using for testing).
If and when this approach gets phased out, what would be the canonical place for this native Canvas code with the addLayer() loop?
Take a look to the sky just before you die; it's the last time you will.
RevHardt
 
Posts: 31
Joined: Tue Jun 10, 2014 3:59 pm
Version: 3.4.0
OS: Win 7 Pro SP1 x64

Re: Get objects to show up on Map/Radar

Postby Philosopher » Tue Mar 24, 2015 4:32 pm

If you want, you can make it ;)
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Get objects to show up on Map/Radar

Postby Hooray » Tue Mar 24, 2015 5:23 pm

the main issue is that kinda everybody agrees that plib/pui (the legacy GUI) needs to be phased out - however, people believe in different approaches.
However, for integrated purposes, we really only have the Canvas-based approach. And even Zakalawe mentioned -despite his Qt5 efforts- that he's contemplating to integrate a Qt5-based GUI with Canvas layers so that there won't be any efforts wasted.

Like Philosopher said, so far, everything is open for debate - and basically nothing is set in stone. Porting the map-canvas.xml dialog to become a native Canvas dialog is actually fairly straightforward to do, we really only need 2-3 widgets (checkbox, button, labels) to make this happen, all of which are already supported/provided by Canvas.

Under the hood, such dialogs would live in $FG_ROOT/Nasal/canvas/gui/dialogs

This is also where you can find existing GUI dialogs, which could be used as "templates" for prototyping the new native Map dialog.
A few months ago, I already prototyped a simple proof-of-concept, by wrapping the existing MapStructure code in a Canvas "widget" that supports styling (see $FG_ROOT/gui/widgets).

http://wiki.flightgear.org/Canvas_MapSt ... map_dialog
Image

Such a MapStructure widget would then also support all other Canvas features, e.g. clipping:
Image

And it would even be possible to show/use the Canvas widget in legacy GUI dialogs:
Image

So this is pretty much the direction we're headed: move away from PUI dialogs and use native Canvas dialogs (also due to much better performance, and no problems with graphics artifacts).
The first step would be wrapping MapStructure as a Canvas GUI dialog - once that works, the more correct approach would be moving this into a custom Canvas widget, so that other GUI dialogs can easily use/show MapStructure-based layers - which would also mean that we need to support multiple widgets (=maps) per dialog. At that point, it would also be possible to dynamically add/edit MapStructure layers using a dialog, i.e. we'd be approaching a situation where we could recursively use MapStructure to create MapStructure layers for all kinds for different purposes.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Get objects to show up on Map/Radar

Postby RevHardt » Wed Mar 25, 2015 12:59 am

To display the areas of effect of the AA units, I want to draw a circle around each on the AA layer. The circle below is drawn directly onto the canvas map as of now, independent of the AA layer.

Image

Code: Select all
var searchCmd = func
                {
                  var myCanvas = canvas.get(cmdarg());
                  var aoe1 = myCanvas.createGroup(); # Nasal runtime error: non-objects have no members
                  var aoe2 = aoe1.createChild('group', 'AoE'); # ^ Above error is not fatal though
                  var xpt = 100; var ypt = 100; var rad = 50;
                  aoe2.createChild('path')
                  .setStrokeLineWidth(1).set('stroke', 'rgba(255, 0, 0, 1)').setStrokeDashArray([1, 1])
                  .moveTo(xpt, ypt).arcSmallCW(rad, rad, 0, xpt + 2 * rad, ypt)
                  .moveTo(xpt, ypt).arcSmallCCW(rad, rad, 0, xpt + 2 * rad, ypt);
                  ...

The problems I'm facing are:
  1. How to get a handle to the AA layer inside AA.lcontroller? Is it via something like me.map.getLayer()? If so, do I simply use createGroup() or something on that object?
  2. How to link the visibility of the AoEs to that of the AA layer itself? Right now, the circle persists even when the layer is checked off, even though the drawing code is in AA.lcontroller.
  3. Arc drawing takes units in pixels and is independent of zoom status. My layer is aware of the latitude, longitude, and AoE radius (in real life units) of each AA unit. How do I convert real life units to pixels while considering the zoom status?
  4. Scaling an additional path/SVG defined in AA.symbol as an AoE indicator depending on zoom and AoE size could be an alternative (a variation of the demo provided here), but I don't know how to use multiple symbols in a single layer.
  5. I would additionally want to fill the AoE circle in a translucent fashion. That will depend on the mechanism of displaying the circle boundary itself, I think.
Wiki pages and Nasal files have gotten me only so far and I don't know how to proceed. Suggestions, please?
Take a look to the sky just before you die; it's the last time you will.
RevHardt
 
Posts: 31
Joined: Tue Jun 10, 2014 3:59 pm
Version: 3.4.0
OS: Win 7 Pro SP1 x64

Re: Get objects to show up on Map/Radar

Postby Hooray » Wed Mar 25, 2015 3:09 am

Just briefly (will respond in more detail later on, unless somebody else beats me to it ...):

I think you are making a conceptual mistake by creating a new layer that writes to another layer - while it would be possible to do something like that, I would suggest to maintain the separation here, or encapsulate both features in a single layer:
  • I would suggest adapting the existing AA layer, or introducing new layer for those "effect range circles"
  • basically, each AA symbol would have its own "effect range", which should be part of the AA layer IMO
  • if you want to make this truly optional, just introduce a completely new layer and reuse the original searchCmd code to come up with the position/offset for each circle
  • you can probbaly look at other layers, e.g. the altitude-profile or VOR/DME layer to see how circles can be optionally added per element (I think the VOR layer will add circles for tuned stations, i.e. 2 stations only)
  • regarding your #3, I think we do have code in at least one of the layers drawing circles using nautical miles, not pixels (but need to check to be sure ...)
  • multiple DIFFERENT symbols per layer can be trivially supported - just look at existing layers doing this, such as the TFC (Multiplayer/AI traffic) layer - in general, the idea is to use caching (which is why it makes sense to understand MapStructure caching concepts first) - but otherwise, there's a pre-created cache of symbols that are dynamically hidden/shown and added/updated as required. Indeed, the difficult stuff is transparently handled, so you only need to look at other layers using caching to see how they work - internally, each styled symbol will be put into a cache and turned into a raster image, which includes vector images (SVGs) - even animated stuff can be supported like this by using a timer/listener to change properties over time.
  • your #5 is most easily accomplished by using OpenVG paths - alternatively, you need to check svg.nas to see if the corresponding Inkscape primitives are already supported or can be easily added

Probably, Philosopher, Gijs and artix can provide additional pointers/help - but in the meantime, I would suggest to look at the aforementioned layers.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Get objects to show up on Map/Radar

Postby RevHardt » Wed Mar 25, 2015 5:35 am

I shall take a closer look at the layers you mentioned, but regarding:
I think you are making a conceptual mistake by creating a new layer that writes to another layer - while it would be possible to do something like that, I would suggest to maintain the separation here, or encapsulate both features in a single layer:
  • I would suggest adapting the existing AA layer, or introducing new layer for those "effect range circles"
  • basically, each AA symbol would have its own "effect range", which should be part of the AA layer IMO
  • if you want to make this truly optional, just introduce a completely new layer and reuse the original searchCmd code to come up with the position/offset for each circle

... I want to clarify that I do not wish to create a new layer at all. My ideal AA.lcontroller would indicate both AA units (it already does) and their AoEs (they don't need to be optional).
Basically, I would like to toggle the display of everything on the Canvas map related to AA with a single checkbox.

I asked about 1. because I wanted to know how a layer can refer to itself in its own lcontroller (isn't me something like this in C++?) and then add paths/groups/children using that handle.
Take a look to the sky just before you die; it's the last time you will.
RevHardt
 
Posts: 31
Joined: Tue Jun 10, 2014 3:59 pm
Version: 3.4.0
OS: Win 7 Pro SP1 x64

Re: Get objects to show up on Map/Radar

Postby Philosopher » Wed Mar 25, 2015 12:30 pm

The best way to add a symbol to a layer is to return it from the lcontroller.searchCmd() method. If you aren't already, you have to wrap it in a "model" object – which can be a simple hash with some fields. You'll probably want lat and lon fields, maybe a type, and perhaps a unique id. For displaying circles, add a range field. Make sure you implement .equals() in you model objects! This allows the code to keep track of models and add/remove them in a smart manner.

The symbol now will take the model and render it onto the canvas. For fields that might change, put their rendering in the .update method (you can even keep track of the last value, so you don't needlessly recreate it), but for constant fields, render it in the .new() method.
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Get objects to show up on Map/Radar

Postby RevHardt » Wed Mar 25, 2015 3:50 pm

My lcontroller.searchCmd() already returns results[], which contains a subset of the models returned by props.globals.getNode("models").getChildren() filtered by required criteria.

Are you suggesting that I add a range field inside the relevant /model/model[<num>] node? If so, when I use:
Code: Select all
model.setDoubleValue("range", 50.0);
... in my lcontroller.new(), what units does that value use? Where do you suggest I put code that uses range to draw the areas of effect onto the existing layer?

As of now, .equals() looks like this inside .new():
Code: Select all
layer.searcher._equals = func(l, r) l.equals(r);

If this won't suffice, I have a few more questions that could be answered by looking at a Nasal file (or two) that implements custom .equals() and .update(). Any particular module(s) that comes to mind? Thanks!
Take a look to the sky just before you die; it's the last time you will.
RevHardt
 
Posts: 31
Joined: Tue Jun 10, 2014 3:59 pm
Version: 3.4.0
OS: Win 7 Pro SP1 x64

Previous

Return to Canvas

Who is online

Users browsing this forum: No registered users and 2 guests