VRManager::instance() was using a function scoped static osg::ref_ptr to
store the VRManager instance. However it needs to be used from
fgOSCloseWindow(), which is called from an atexit handler, and C++11
specifies that static object destruction and atexit handlers are reverse
sequenced, i.e. a static object initialised after an atexit call will be
destroyed before the atexit callback is called.
On Windows this can result in the osg::ref_ptr being destroyed (and
hence set to NULL) before fgOSCloseWindow() tries to call
destroyAndWait() on the instance.
Fix the resulting seg fault by moving the ref_ptr object to static file
scope so it is default constructed before the atexit call, and using
only a simple static bool to initialise it on first call to
VRManager::instance().
Reported-by: Alan Teeder <ajteeder@v-twin.org.uk>
fgInitAircraft() loads the aircraft -set.xml file, which calls
ResourceManager::findPath() for each 'include=...' directive. In order
to prevent such includes from triggering the new warning printed by
ResourceManager::findPath(), call fgInitAllowedPaths() after the
aircraft paths have been updated and before the -set.xml file is loaded.
Thanks to Alan Teeder for reporting the problem.
We can now probably remove the call to fgInitAllowedPaths() after
processOptions() in fgStartNewReset() (I believe the newly-added call
comes “soon enough”). Not doing so in this commit, though: let's fix
problems before optimizing.
This is an additional call to fgInitAllowedPaths(), earlier than the
normal one. It doesn't know the paths given to --allow-nasal-read, but
can already authorize read access for all of $FG_ROOT. This allows one
to add SGPath::validate() checks for paths given to
ResourceManager::findPath() with a non-null second argument (without
this change, the validation would fail for files included from
defaults.xml, read by fgSetDefaults() before the definitive
fgInitAllowedPaths() call has been performed).
The previous way only worked because after trying
SGPath(aContext, aResource), ResourceManager::findPath() tries all
providers, among which there is a BasePathProvider with $FG_ROOT as its
base... provider which doesn't use the 'aContext' argument at all.
Move the fgValidatePath() code and the two associated static variables
'read_allowed_paths' and 'write_allowed_paths' to SimGear.
fgValidatePath() is now known as SGPath::validate(). This requires
SimGear commit e002a481f481709263a.
osgXR 0.5.0 broke the API slightly, so update VRManager to use the new
enumeration names and update the required osgXR version for when using a
system version of osgXR.
Signed-off-by: James Hogan <james@albanarts.com>
Update 3rdparty/osgXR to version 0.5.0, which primarily gets us build
fixes for Windows. Unfortunately one of them requires an API breakage to
avoid some apparent preprocessor namespace pollution on Windows, which
will require minor source modification in FlightGear (left to the next
commit). The ABI is unchanged so binary compatibility is unaffected.
- Use the complete path when performing the existence check (previously,
only the directory part was used: bug in commit
8853fded29).
- Use the resolved path (SGPath instance) obtained from
FGGlobals::resolve_maybe_aircraft_path() when constructing the
SGSoundSample instance; this makes it possible to use paths starting
with the '[addon=...]' special prefix (handled by the
AddonResourceProvider) with FGSoundManager::playAudioSampleCommand(),
and therefore with the 'play-audio-sample' FGCommand.
This requires SimGear commit 8febf6b9f58e9a1919ff3 ("SGSoundSample
constructor changes").
Before this commit, if several menu entries (possibly in different
menus) had the same label after translation and latin1-ization by
FGLocale::utf8toLatin1(), selecting one of them used to fire the
bindings associated to all such entries. This is because the bindings
used to be stored in an std::map whose keys were the
translated-and-latin1-ized labels.
This commit fixes the problem in the following way:
- the std::map (_bindings) is turned into an std::forward_list;
- each element of this std::forward_list references the bindings
assigned to a menu entry;
- in order to allow FGPUIMenuBar::fireItem() to find the bindings
assigned to the menu entry that triggered it,
FGPUIMenuBar::make_menu() calls puMenuBar::add_submenu() with an
additional argument ("user data") that attaches to the puObject for
each menu entry a pointer to the relevant element of _bindings.
Note: given how the menubar is created, an std::vector wouldn't be
appropriate for _bindings, because we need the pointers to its elements
to be stable when new elements are added to _bindings.
Reported by Wayne Bragg: https://sourceforge.net/p/flightgear/mailman/message/37682605/
FGButton::init() passes the module parameter (a non-const string
reference) straight through to FGCommonInput::read_bindings() as a const
reference.
Change the FGButton::init() signature so that module is const there too,
so that callers can pass it const string references returned by
accessors without having to make copies.
Use a quad composition layer object from osgXR 0.3.9 to make the splash
screen VR friendly. This allows the OpenXR compositor to redraw the quad
without any updates from flightgear, which is particularly helpful as
flightgear makes no attempt at a reasonable VR frame rate during
initialisation.
The quad is positioned 2 meters from the user, with an aspect ratio
matching the desktop window. The quad is blended using an
unpremultiplied alpha channel which is forced to a given alpha value by
osgXR.
The splash is effectively already rendered to an FBO as non-linear SRGB,
so this is made explicit in the internal texture format, with the
rendering to the desktop window using GL_FRAMEBUFFER_SRGB to ensure it
is properly re-encoded.
Move the splash screen from the scene root to a camera group camera,
just below the GUI camera. This has a number of advantages, mainly VR
related:
- The splash FBO will only be rendered once per frame. Currently it
appears to be rendered for both near & far cameras, and with
stereoscopic rendering for both left & right (even though it splats
right across both views at the moment), so 2 or 4 times.
- It makes it possible to render the splash fullscreen on the desktop
window, while presenting it on a 3d quad in VR (possibly via an
OpenXR composition layer so the runtime can keep rendering it
smoothly while FlightGear framerate drops during loading.
Update 3rdparty/osgXR to version 0.3.9, which gets us better handling of
quirks and window closure, and the ability to create quad composition
layers which will be particularly useful for the loading screen when
flightgear isn't so good at timely frame updates.
We were not appending the video container suffix if there was already a '.' in
the name.
Part of this fix is also to simplify the code - if name_in is not "" we don't
attempt to create softlink or append /sim/video/container.
Avoid a console warning from OpenAL-soft about leaked buffers on
shutdown, by ensuring IAXClient backend does matching cleanup
for the buffers it allocates.
* Parking with point beyond parking so aircraft don't stop early
* Better approach routes (wait pattern)
* Extracting vector math from AIFlightplan
* More use of SGPositioned in ATC
The launcher diagram and navaid-search now include TACANs, using
the current NavCache encoding (DME whose name ends in TACAN). A new
‘—tacan’ option works similar to —vor etc to set position (with
optional offset).
Tuning the Tacan instrument from the command line is not yet supported,
but could be easily added.
upper_case_property causes valueChanged to fire twice, since
SGPropertyNode string storage is now immutable (std::string). This
caused double-processing of for example adding a waypoint in
the route-manager dialog. Since the InputListener already upper-cases
the string, we can simply remove the upper-case property logic.