+ The panel(s) are now an first-class SSG node inside the aircraft
scene graph. There's a little code added to model.cxx to handle the
parsing, but most of the changes are inside the new FGPanelNode
class (Model/panelnode.[ch]xx).
+ The old FGPanel source changed a lot, but mostly cosmetically. The
virtual-cockpit code moved out into FGPanelNode, and the core
rendering has been abstracted into a draw() method that doesn't try
to set any OpenGL state. I also replaced the old inter-layer offset
code with glPolygonOffset, as calculating the right Z values is hard
across the funky modelview matrix I need to use. The older virtual
panel code got away with it by disabling depth test, thus the "panel
draws on top of yoke" bug. PolygonOffset is really the appropriate
solution for this sort of task anyway.
+ The /sim/virtual-cockpit property is no more. The 2D panels are
still specified in the -set.xml file, but 3D panels are part of the
model file.
+ You can have as many 3D panels as you like.
Problems:
+ The mouse support isn't ready yet, so the 3D panels still aren't
interactive. Soon to come.
+ Being part of the same scene graph as the model, the 3D panels now
"jitter" in exactly the same way. While this makes the jitter of
the attitude gyro less noticeable, it's still *very* noticeable and
annoying. I looked hard for this, and am at this point convinced
that the problem is with the two orientation computations. We have
one in FGLocation that is used by the model code, and one in
FGViewer that is used at the top of the scene graph. My suspicion
is that they don't agree exactly, so the final orientation matrix is
the right answer plus the difference. I did rule out the FDMs
though. None of them show more than about 0.0001 degree of
orientation change between frames for a stopped aircraft. That's
within an order of magnitude of what you'd expect for the
orientation change due to the rotation of the earth (which we don't
model -- I cite it only as evidence of how small this is); far, far
less than one pixel on the screen.
[and later]
OK, this is fixed by the attached panel.cxx file. What's happened is
that the winding order for the text layer's polygons is wrong, so I
reverse it before drawing. That's largely a hatchet job to make
things work for now, though. We should figure out why the winding
order is wrong for only text layers and fix it. I checked the plib
sources -- they're definitely doing things CCW, as is all the rest of
the panel code.
Odd. I'm also not sure why the 2D panel doesn't care (it works in
both winding orders). But this will allow you to check in working
code, anyway. There's a big comment to this effect in there.
- changed FGSubsystem::update(int) to
FGSubsystem::update(delta_time_sec); the argument is now delta time
in seconds rather than milliseconds
- added FGSubsystem::suspend(), FGSubsystem::suspend(bool),
FGSubsystem::resume(), and FGSubsystem::is_suspended(), all with
default implementations; is_suspended takes account of the master
freeze as well as the subsystem's individual suspended state
- the FDMs now use the delta time argument the same as the rest of
FlightGear; formerly, main.cxx made a special case and passed a
multiloop argument
- FDMs now calculate multiloop internally instead of relying on
main.cxx
There are probably some problems -- I've done basic testing with the
major FDMs and subsystems, but we'll probably need a few weeks to
sniff out bugs.
What the attached patch does is map your panel definition onto a (non
z-buffered) quad in front of your face. You can twist the view around
and see it move in the appropriate ways.
Apply the patch (let me know if folks need help with that step), and
then set the /sim/virtual-cockpit property to true. You can do this
on the command line with --prop:/sim/virtual-cockpit=1, or via the
property picker. Bind it to a key for fast toggling if you like.
The default bindings don't allow for "panning" the view, so you'll
have to modify yours. These are the mappings to my joystick's hat
switch, for those who need hints:
<axis n="6">
<desc>View Direction</desc>
<low>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/sim/view/goal-offset-deg</property>
<step type="double">1.0</step>
</binding>
</low>
<high>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/sim/view/goal-offset-deg</property>
<step type="double">-1.0</step>
</binding>
</high>
</axis>
<axis n="7">
<desc>View Elevation</desc>
<low>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/sim/view/goal-tilt-deg</property>
<step type="double">1.0</step>
</binding>
</low>
<high>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/sim/view/goal-tilt-deg</property>
<step type="double">-1.0</step>
</binding>
</high>
</axis>
While the current implementation is happy with just plastering the
panel's notion of "screen" into the 3D world, this is actually more
general. Each panel can, in principle, have it's own coordinate
system, and you could build a cockpit out of a bunch of them. The
mapping is specified by providing a 3D coordinate for three corners of
the quad the panel should be mapped to; this should be pretty simple
to work with.
All that's needed for a perfectly general solution is a convention on
where to store the information (a cockpit xml file, or put it in the
aircraft -set file, or...), and some work on the panel's coordinate
system conventions (some of which don't coexist very nicely with a
generalized 3D environment). Combine that with a plib model for the
non-panel interior of the cockpit, and we're golden.
I'm actually really pleased with this. It worked better and more
quickly than I could have imagined, and impact on the surrounding code
is quite light -- a few property tests only. But some stuff is still
missing:
+ No equivalent work was done to the HUD, so it still displays
incorrect headings when the view changes. The use of pixel
coordinates deep in the HUD code is going to give me fits doing the
port, I sure. It's not nearly so well put together as the panel
(where I just changed the setup code -- none of the rendering code
changed at all).
+ I forgot that the panel was clickable. :) Input events still have
the screen coordinates, which essentially kills the interactivity
when in virtual cockpit mode. This won't be hard to fix; it's only
broken because I forgot the feature existed.
And one note about the implementation choice: to get away from the
inevitable near clip plane issue, the virtual cockpit renderer simply
disables the z buffer. This means that cockpits built using these
panels need to be z-sorted, which isn't too hard since they are static
geometry. It also means that no two "virtual panels" can ever be
allowed to interpenetrate. No biggie.
(i.e. multiloop). Most subsystems currently ignore the parameter, but
eventually, it will allow all subsystems to update by time rather than
by framerate.
with different modifiers (the format of the key bindings has changed
again slightly, adding a <code>..</code> element; see keyboard.xml for
details).
2. Modified FGInput to try default modifiers for ctrl, shift, and alt
when the initial bindings fail (i.e. you don't have to specify
mod-shift explicitly for upper-case 'P' any more).
3. Fixed problems with properties and panel reloading reported by
Martin Dressler and John Check.
4. Updated preferences.xml to get rid of obsolete references to
/controls/brakes/left and /controls/brakes/right (as reported by John
Check).
There were also two non-bugs reported by John Check:
(a) Differential braking doesn't work (John was using the obsolete
properties from #4 above).
(b) Duplicates show up in the property tree using the telnet interface
(the property tree doesn't show indices, and John was seeing separate
entries for each possible engine, etc.).
I have a scrollable panel working (it didn't take long in the end). A
panel can now be much wider or higher than the available area, and the
user can scroll around using [Shift]F5, [Shift]F6, [Shift]F7, and
[Shift]F8. The user can also scroll the panel down to get a bigger
external view. Mouse clicks seem still to be working correctly.
To set the panel's (virtual) height and width, use the panel file's /w
and /h properties in a panel XML file; to set the initial x- and y-
offsets (untested), use the panel file's /x-offset and /y-offset
properties; to set the initial height of the external view (untested
and optional), use the panel file's /view-height property. Note that
none of these show up in the regular FGFS property manager.
Unfortunately, these patches will not affect your initialization
problems with the property manager -- I'm having a hard time tracking
them down because I cannot reproduce them.
I have also made some patches to main.cxx and views.cxx to do two
things:
1. Expand or shrink the external view as the panel moves up and down.
2. Set the window ratio correctly, so that we don't get an oval sun
and flat clouds when the panel is visible (the problem before was
integer division, so I added casts).
Unfortunately, the window ratio is not set properly at start-up --
there are too many dependencies, and I haven't figured that part out
yet. As soon as you hide and redisplay the panel or move it
vertically (i.e. force fgReshape to be called), you'll see the correct
ratio.
I've done some substantial reengineering of the 2D panel: except for the
radios, the whole panel is built from a large table now. I'd be
grateful if you could add these changes to the main distribution.
Since I always like to provide some eye-candy with my updates, I've
fixed the ADF gauge to be more usable by slimming the needle and adding
markings every 45 deg (you'll need to use the attached textures).
- the panel uses much, much less texture memory, and draws much
faster, at least on my hardware
- there is a wet (magnetic) compass at the top of the panel
- the gyro compass shows true heading again, but don't get used to it:
we're going to set it up to drift soon
- there are TO/FROM flags on NAV1 and NAV2 (but no GS flag yet)
- the ADF looks a little more realistic (if you can forgive the ugly
needle)
- when the HUD is not open, the framerate is moved to the right side
of the screen so that it won't be obscured by the mag compass
- knobs now continue to rotate when you hold down the mouse
- the middle mouse button makes knobs rotate much faster
- there are NAV1, NAV2, and ADF radios that can be tuned using the mouse
- there are standby frequencies for NAV1 and NAV2, and buttons to swap
- there is a crude, rather silly-looking DME, hard-wired to NAV1
- there is a crude, rather silly-looking autopilot that can lock
the heading (to the bug on the gyro), can lock to NAV1, and can lock
the current altitude
- the knobs for changing the radials on NAV1 and NAV2 look much better
and are in the right place
- tuning into an ILS frequency doesn't change the displayed radial for
NAV1
Code
- I've created a new module, sp_panel.[ch]xx, that constructs the
default single-prop panel; this works entirely outside of FGPanel,
so it is possible to construct similar modules for other sorts of
panels; all code specific to the default panel has been removed from
panel.cxx
- current_panel is now a pointer
- radiostack.[ch]xx keeps track both of the actual radial and of the
selected radial (they will differ with ILS); the NAV gauges should
not spin around automatically to show the actual radial (we need to
do something similar with the autopilot)
- the panel is initialized fairly early
- make sure that standby frequencies also get initialized
- I've started combining and clipping small textures to save texture
memory; there's a lot more to do, but at least I've made a start
Externally: added a chronometer and a control-position indicator a la
MSFS, along with dummies for the radio-nav gauges.
Internally, substantially reworked the code so that the individual gauges
can be table- (and eventually, file-) driven.
I've reorganized the code in panel.cxx and panel.hxx so that it will
be a little easier to extend the panel later if someone wants to.
It's still basically Friedemann's code at the core, but I've
repackaged it into a saner class hierarchy and encapsulated as much as
I could (there are still a couple of circular dependencies that need
swatting). If someone wants to modify it to use SSG or to add new
gauges, it should be a lot easier now.
There are no user-visible changes.