Set up the default camera as a mirror of the VR view when needed, using
a new CameraInfo flag named VR_MIRROR based on a camera property
"vr-mirror" which is set on the default camera group. When set this flag
causes the compositor to be constructed (and reloaded) using
buildVRMirrorCompositor() and osgXR's mirror camera setup code, rather
than the usual Compositor::create().
Implement VR mirror properties and associated getUseMirror() accessor:
- /sim/vr/mirror-mode: This will allow the user to control the VR
mirror via a GUI.
- /sim/vr/mirror-enabled: This isn't written, but is used by
getUseMirror() in combination with isRunning() to determine whether
the mirror should be used.
Use the newly added simgear::Compositor::resetOrderOffset() to reset the
order offset counter with each compositor reload. This prevents the
counter increasing indefinitely, which soon results in render orders
beyond those set statically for the GUI and upcoming VR mirror.
Patch by Michael Danilov: allow an aircraft set XML to define the requied
directory name, and if one is provided, validate the actual name against
this. This catches common issues where a manually downloaded aircraft
has the wrong name and some assets will therefore not load.
SF-Ticket-ID: https://sourceforge.net/p/flightgear/codetickets/2647/
Implement support for virtual reality headsets via version 0.3 of the
osgXR[1] library I've been working on which uses OpenXR.
Add a new VRManager class based on osgXR::Manager to implement its
callbacks. When osgXR needs a new view created, we build a new camera in
the default camera group, and notify osgXR of each new "scene" typed
render pass. It also hooks into the CameraInfo's new compositor reload
callback to ensure osgXR is updated when the compositors are reloaded.
VR settings are controlled by properties, and new --enable-vr /
--disable-vr options are implemented to enable/disable VR at start.
This is enough to get basic VR for looking around the cockpit, but more
work will be required to support a desktop mirror of VR view, VR splash
screen, VR GUI, controller interaction, and correct positional sound.
[1] https://github.com/amalon/osgXR
* Relax runway exit route requirement to 80°
* Ensure parking is only reset if airport for AI aircraft has changed
* Heading Error signed and arrival lead distance
This was a long-standing issue where Canvas cameras were rendered
multiple times, once per slave camera. In the case of the Classic
pipeline they were being rendered twice.
Making them slave cameras has the issue of them not being shared
across GraphicsContexts anymore, so it's not possible to see Canvas
displays in extra CameraGroup windows. This is fixed by using OSG
context sharing feature and sharing the initial windows' context
with all subsequent windows.
Add a compositor reload callback object to CameraInfo, with callbacks
for just prior and after the CameraInfo's compositor is reloaded by
reloadCompositors().
This will allow VR cameras to be reconfigured after a reload.
Add removeCamera() method to CameraGroup to find and remove a single
CameraInfo.
This will allow cameras created for VR to be dynamically reconfigured.
Since 'center on aircraft' is now persistent, we need to expliictly init
this value when showing the map. Thanks to Michael Danilov and Colin
Geniet for the fix.
SF-Id: https://sourceforge.net/p/flightgear/codetickets/2637/
Reversed the affect of mouse in some legacy views, e.g. Helicopter and Pilot
views now move in expected direction for mouse drags. Also increased scale
of movement to make things similar to the default view system.
In chase view etc, apply mouse movements after damping of aircraft orientation,
previously mouse movements were getting damped.
Removed SviewStepFinalToTarget. SviewStepFinal now automatically aims at target
if new posdir.target_is_set flag is true.
Improved double views: Avoid duplicate SviewStepCopyToTarget step. Disabled
mouse drag handling - was gives weird results and is not required or
helpful. Be more consistent in using target position if available, otherwise
eye position; for example using a Helicopter view to create a double view now
uses the target of the helicopter view, not the eye point, which works much
better.
Removed internal use of SviewStepFinal from SviewStepDouble - used to be
special case.
Split mouse drag handling out of SviewStepRotate into new SviewStepMouseDrag.
Simplified last-pair code - both last-pair and last-pair double find position
and target in the same way.
Added <startup-current> param. Default is false which preserves previous
behaviour where internal state is initialised to zero. Otherwise we initialise
internal state using the current error value, which can reduce oscillations.
Added <startup-its> param, default is zero. For the first <startup-its>
iterations we don't update the output, which can be used to cope with initial
bad data from earlier controllers.
Also refactored the code to hopefully make it clearer and modified debug
logging to output all info in a single statement and on a single line for
clarity.
For example avoid initial oscillations with:
<pid-controller>
..
<startup-current>true</startup-current>
...
</pid-controller>
Ever since support for CompositeViewer was added in f62e5b9ce3,
FGEventHandler::eventToViewport() has been always calling
window_builder->getDefaultWindow() so it could decide whether an event was for
the main window or not. But if a custom camera-group was specified, there would
be no existing window called 'FlightGear' so getDefaultWindow() would create
one, which then interfered with event handling.
The fix is to change the global WindowBuilder::defaultWindowName to match
sim/rendering/camera-group/gui/window/name when we are handling a custom
camera-group, which ensures that when FGEventHandler::eventToViewport() calls
window_builder->getDefaultWindow(), it gets the main window, not a new window
called 'FlightGear'.