Board index FlightGear Development Nasal

create terminal buildings with Nasal ?

Nasal is the scripting language of FlightGear.

create terminal buildings with Nasal ?

Postby pommesschranke » Fri Dec 26, 2014 2:09 pm

let's assume that downloading the footprint of an airport terminal building from OSM/overpass turbo is fast enough.
Can Nasal create an object and put into the scenery in RAM/on the fly without writing an .ac file to the filesystem ?
Posts: 1092
Joined: Sat Apr 27, 2013 7:58 pm
Location: EDLM & LJCE
Callsign: d-laser
IRC name: laserman
Version: git
OS: Linux Lubuntu 14.04

Re: create terminal buildings with Nasal ?

Postby Hooray » Fri Dec 26, 2014 5:56 pm

Not yet the way you envision - currently, the "proof-of-concept" work around would indeed be usign $FG_HOME and procedurally creating *.ac files there dynamically.
However, I've been in touch with radi about doing exactly this a few times - the basic idea is to use Stuart's random buildings routines and expose those to Nasal space via cppbind, this would then only require a way for the geometry to be configurable from Nasal space, which would typically require exposing the various osg::Vec* classes to Nasal.
A few weeks ago I talked with Thorsten about this, and he said things might not be as straightforward given his understanding of the random buildings code.

Personally, I believe that random buildings are preferable given their low impact on frame rate - but the other option would be modifying the model manager to allow models to be declared procedurally.

I've quite a few private messages that I could post here, but need to get in touch with Thorsten and others first to see if they don't mind things being posted here now - here's some of the stuff I wrote back then:

Hooray wrote:To allow buildings/outlines and dimensions to be specified dynamically, we'd only need to be able to populate an OSG vector based on a Nasal vector, as per: ... n.cxx#L225

This kind of stuff can be trivially moved to Nasal space, where a conventional Nasal vector would be used to populate the osg::Vec3, so that there's only run-time overhead during initialization. Afterwards, it will be just C++ data structures that are passed around, without even the GC having to be involved.

STL vectors are already supported by the C++ bindings framework, so making building dimensions configurable would be straightforward.
placement-wise I still need to look at the other code to see if/how heuristics could be customized without having to be hard-coded.
At that point, a hybrid approach using shaders and arbitrary noise functions could be used without necessarily having to touch any C++ code afterwards.

Like I said, as usual, I am not interested in the full solution, but only in providing the infrastructure so that this can be developed without people having to face the core development bottleneck. Also, this doesn't necessarily have to involve any Nasal (using Nasal would just seem natural and straightforward to me), some kind of extended materials/XML dialect would also be possible - but I kinda believe in the flexibility provided by a hybrid approach, without Nasal nececessarily having to be called at frame rate - i.e. the building/city generator would merely be "configured" and customized during initialization/tile entry, which would populate C++ data structures - i.e. those currently hard-coded (dimensions, placement heuristics) - while everything else would remain "as is".

Equally, this would mean that geometry creation would not be specific to buildings/cities, but that arbitrary geometry could be dynamically created for other purposes easily and added to the scene - e.g. for procedurally creating bridges by assembling them from a handful of parameterized building blocks and connecting all meshes involved.

Given all the OSM activity, I am getting the impression that core development is a very real bottleneck, and that all the Python development is not easily deployed - so some kind of dedicated framework would make sense, no matter if a city generator will evolve immediately or not.

In my opinion this isn't unlike the journey that LW/AW has taken: these features need first of all a certain basic infrastructure, specific feature requests are more likely to be implemented once a proof-of-concept has been shown to work sufficiently well.

Depending on your familiarity with modern C++ and the STL/OSG, you may find the CppBind article pretty straightforward to work through - but I also have a topic branch where I am adding procedurally-created geometry (via Nasal) to a tile by wrapping OSG types into Nasal "ghosts" (where a "ghost" is a simple wrapper for a C++ smart pointer, exposed via the CppBind framework). In other words, exposing that part is straightforward - and I could share that code if you should consider that useful/instructional:

So, to sum it up, I would love to see such features to be be incrementally moved to $FG_ROOT, so that OSM/autogen stuff would not necessarily require large-scale C++ modifications - ideally implemented using shaders/effects - maybe in combination with a little Nasal glue code to initialize a few data structures that are currently hard-coded. I very much believe that things like PixelCity could be re-implemented inside FlightGear on top of a modified "random buildings systems", a few scripting space bindings and the effects/shader system.
Personally, I don't think that, post 3.2, such features should still be supported by the fixed-pipeline back-end - i.e. could definitely require GLSL support.

Hooray wrote:thanks for the feedback, you are raising some fair points, and I may have to revisit/reconsider some ideas ...
so just briefly:

  • I was only referring to the vectors for creating individual buildings, to create a C++ instance - that way, we could even re-use a few conventional Nasal vectors in a for loop
  • there is a way for marking elements so that they are not used by the GC - so that would be another option
  • clouds are using so called "fgcommands", which are channeled through the property tree, it's a very simple, and even crude, mechanism - you kinda need to come up with a property structure for marshalling all possible arguments. Even without using Nasal, there should be better options.
  • I'd also like to see more/better autogen support in FG, even unrelated to Nasal in particular, I also agree with your points about resource utilization, as you know - but currently, we are seeing a new feature being developed primarily in python, i.e. not necessarily "directly" useful to FG. We tend to use the term "prototyping" for coming up with solutions that stay around for years - so there's that, too. And I think it would be better for FG to provide at least /some/ dedicated infrastructure to "channel" these contributions, to ensure that they're future proof - I am currently not seeing that ...

My understanding of the code may be incomplete, especially WRT OSG-level threading, but I basically understand how to expose hooks in order to add procedurally-created geometry to the scene - while I've been toying with Nasal so far, some other approach would also be possible (i.e. to avoid GC issues).

But obviously, being able to use a more "standard" approach (think geometry shaders) would obviously also be cool. The question then is what data is needed and how it can be exposed in terms of APIs, to allow people to continue experimenting with these features, without necessarily having to agree on all counts.

From a graphics standpoint, geometry shaders + openCL sound like they would solve quite a few problems, while sacrificing portability - otherwise, the truth is that we cannot expect to make our scene increasingly complex without also using the right tools for the job - and Nasal+random buildings would certainly be inferior performance-wise to geometry shaders combined with a few APIs for processing vector data.

But currently we're apparently facing a dead-end, as can be seen by Stuart's repeated statements on being willing to phase out his work in this department.
Personally, I just don't see these features being completely rewritten/re-implemented - so, I'd rather split up functionality and expose parts of it to fgdata space - no matter if that means XML, Nasal or other infrastructure.

I am not saying I am right about this, it's just my impression about the situation, trying to come up with a feasible solution.
All the python stuff could otherwise end up being really useful, but increasingly hard to deploy/use.

So, I'd rather not end up with a FG project being split with an increasing number of incompatible, but desirable, features (think autogen, osgEarth, rembrandt etc)

Hooray wrote:like I said, you are raising a few issues that I may have been unaware of/to optimistic about - it is obviously straightforward to instance a single object, making this work for large sets of buildings is a completely different matter, which is why I was hoping to reuse Stuart's code here.

and yes, I am thinking of some Nasal-accessible method (library function, fgcommand or even some kind of listener interface analogous to /models, /ai or /canvas) for procedurally creating/adding geometry (without it necessarily being specific to just buildings). For instance, if people are strongly concerned about adding Nasal to a critical system like the terrain/scenery system, we could also have /meshes in the property tree, along with a subsystem that monitors writes to this location (implementing SGPropertyChangeListener) for creating meshes and instancing those.
I would find this a bit awkward to work with at first glance, and more work to implement than going with Nasal - but then again, I've also been wrong about procedurally-creating and updating RTT (canvas) :D
So let's say there's a "black box" method for defining a mesh and instancing it in arbitrary locations - this black box would then be "configured" by vector data or other placement heuristics.

I don't favor geometry shaders - and I do realize that we'd sacrifice portability, but it would seem like a logical step to me, and like a good argument against Nasal or other fgcommands.
Obviously, with fgcommands -or a dedicated SGSubsystem/SGPropertyChangeListener implementation- there would be zero Nasal GC overhead, because Nasal would only ever invoke this system by setting a bunch of properties to call some hard-coded APIs.

Internally, this works such that you can come up with a class that implements a valueChanged() method - which is invoked whenever a property tree/sub-tree is modified, which is then where you can do all kinds of "validation", i.e. to ensure that all required parameters are set and valid (think lat-deg/lon-deg nodes, and having the right type/format and range of values). This is exactly how the /models, /ai and /canvas system get away without requiring a dedicated Nasal interface (bindings) - i.e. it's a bit awkward and verbose, but it's C++ code after all, so sufficiently fast. And fgcommands are straightforward to understand, too - I once wrote a tutorial: ... FlightGear

This is basically the 90s-style "API", listeners were added afterwards and were hardly used for ~10 years, until people started modeling entire subsystems on top of this structure. Obviously, our property tree is single-threaded, so there's no chance for race conditions, but also not much of an opportunity for leveraging OSG-level parallelism once this method is used (even though fgcommands can process their own/private tree - e.g. allocated via

But once someone understands classes and OO, even a full listener-based subsystem is pretty straightforward to implement:
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,
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Posts: 10759
Joined: Tue Mar 25, 2008 8:40 am

Re: create terminal buildings with Nasal ?

Postby psadro_gm » Fri Dec 26, 2014 6:20 pm

Remember though, the reasons why the random buildings code is so optimized:
- multiple buildings are grouped using a single osg::Vec* array
- they all share the same texture atlas.

This ensures the GPU only needs a single state change to render all of the buildings in one pass.

Opening this up to nasal would require very careful management to group objects. Creating single models (or even worse - using multiple textures on a single models) can quickly escalate to no fly zones like Paris.
8.50 airport parser, textured roads and streams...
Posts: 750
Joined: Thu Aug 25, 2011 2:23 am
Location: Atlanta, GA USA
IRC name: psadro_*
Version: git
OS: Fedora 21

Re: create terminal buildings with Nasal ?

Postby Thorsten » Fri Dec 26, 2014 6:38 pm

Opening this up to nasal would require very careful management to group objects.

We are doing a Nasal interface for clouds though - so one would simply structure the code along these lines.
Posts: 8923
Joined: Mon Nov 02, 2009 8:33 am

Re: create terminal buildings with Nasal ?

Postby Hooray » Sat Dec 27, 2014 8:03 am

the cloud interface is fairly low-level in comparison to what's possible in Nasal space (the cloud interface is using fgcommands, where parameters and return values need to be marshalled into property tree nodes). Also, Stuart has repeatedly stated on the forum, and the devel list, that he's considering additional optimizations at the C++/OSG level, so I think we shouldn't re-invent the wheel, but "simply" expose the geometry declaration to Nasal space, so that things are configurable via scripts (or even just xml/properties).
Nasal can already be mis-used (as can C++ or any other language), so I don't see any difference here - ideally, we'd just be piggybacking things onto Stuart's existing code, by removing the "random" part, and by allowing geometry to be customized externally (at run-time), without requiring rebuilding/restarting FG.
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,
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Posts: 10759
Joined: Tue Mar 25, 2008 8:40 am

Return to Nasal

Who is online

Users browsing this forum: No registered users and 1 guest