Priority scheme for tile loading/removing
Cleaner tile manager interface for AI/groundcache/...
Reduce start-up delay. Drop splash screen when inner scenery is available.
Be nice to osg loader: slow-down main loop while initial scenery is still loading.
Again, the previous commit did not complete for some reason.
Modified Files:
configure.ac src/AIModel/AIBase.cxx
src/ATCDCL/AILocalTraffic.cxx src/FDM/Makefile.am
src/FDM/flight.hxx src/FDM/LaRCsim/LaRCsim.cxx
src/Main/Makefile.am src/Main/fg_init.cxx src/Main/main.cxx
src/Main/viewer.cxx src/Main/viewer.hxx
src/Scenery/tilemgr.cxx src/Scenery/tilemgr.hxx
Partition depth in CameraGroup:
Remove the ViewPartionNode scenegraph node. The split rendering of the
scene, done to avoid Z buffer precision problems, is now done by two
slave cameras of the viewer.
Rename FGManipulator to FGEventHandler.
Remove virtual member functions that aren't required for event handlers.
Begin using camera group properties to update cameras at runtime;
Initially only the viewport properties are used.
When no camera group is found in the property tree (the default),
create the properties for one. Expose the default window by name.
Add a test for Boost headers to configure.ac. Boost is now a
dependency.
Remove GLUT and SDL versions of the OSG graphics.
From Till:
i started the project at the end of february with a simple idea: move all
3d-model loading to the DatabasePager-thread. my first attempts looked
promising, though they were a little too optimistic (or naive?). the patch
has evolved a lot since.
currently it does the following things:
1. revive SGModelLib, move functions for xml-model-loading there
2. replace all calls to sgLoad3dModel with calls to either
SGModelLib::loadModel() or SGModelLib::loadPagedModel()
almost all models will be loaded by the DatabasePager. the few exceptions are:
your own plane, shared models in scenery, random objects, AIBallistic models.
3. simplify mode-loading functions (avoid passing around fg_root)
4. avoid supurious MatrixTransform nodes in loaded models
5. fix some memory leaks
Make an OSG file reader for .stg files.
New class flightgear::SceneryPager, which is a subclass
osg::DatabasePager to handle explicit delete requests.
Modify FGNewCache, FGTileEntry, and FGTileManager to use
SceneryPager. Mostly this involved removing the queues that talked to
FGTileLoader.
Calculate accurate tile timestamps from the time they are traversed in
the cull stage (which means that they are visible) instead of updating
them periodically.
Replace tile entry transform and range node with one LOD node
Some cleanup in tileentry.cxx, but mostly code to implement loading of tiles
and their models without reference to FGTileEntry or SGBucket structures.
Also, don't do deferred model loading; load them when the tile is loaded.
* it says it's a warning (while in fact it's just saying what it's doing)
* the user can't do much here (yes, flying slower, but it doesn't say that :-)
* scrolling those countless messages in the terminal puts stress on the CPU
in a time when it's apparently already struggling
implement FGNasalModelData class for execution of XML <load> and <unload>
scripts. modelLoaded() is called by the model loader, and the destructor
on branch removal.
modelmgr.cxx:
tilemgr.cxx:
tileentry.[ch]xx:
make scenery and custom objects run their Nasal scripts on loading
and unloading. Let OBJECT_STATIC object not be cached.
* in some cases more specific sg exception types were used in place
of the more generic one, e.g., sg_io_exception instead of sg_exception
when the context of the error was an IO error
* in some cases, the error message was made more specific
* minor style fix for exception rethrowing --- using throw; whenever
a re-throw is made; sometimes optimizing away the exception symbol name
in the catch handler at all
* more specific catch handlers added in some places -- e.g.,
an sg_io_exception caught ahead of sg_exception
metar fetcher. Effectively this caused the metar thread and the main
thread to both attempt to fetch weather data. This could lead to long pauses
when the main thread decided to fetch the weather, and introduced a race
condition that could cause a segfault/crash.
Investigating this issue, I discovered that even longer ago, someone confused
#defines and #ifdef symbols with C/C++ variables. If I #define XYZ 0 it is
defined so #ifdef XYZ is true, not false like a variable. Our thread
detection made this mistake and there were follow up patches to work around
it.
So I fixed the configure script (ahhh, reading the autoconf manual is highly
recommended excercise for people editing the configure.ac file.) I also
discovered that we were hardwiring with_threads=yes with no way via configure
options to disable threads from the build so I fixed that.
Then I patched up the #ifdef's scattered through the code to match the
configure script changes, oh and by the way, I stumbled upon a past typo
that led to the race condition in the metar fetching thread and fixed that.
I tried to make sure accessor functions which return by reference act
on const objects. also replaced some iterators with const_iterator
and a few return/pass by reference that were missed the first time
around.
There was a patch from Manuel Masing a few months ago which cleaned up
SGLocation's way depending on input values. That means that with that patch
SGLocation does no longer have calls with unneeded input arguments.
I took his patch and integrated that into flightgear and made maximum use of
that changes.
Erik Hofman:
Remove some duplicate code that was moved to simgear/compiler.h
I have prepared a patch that:
- Introduces a FGTileMgr::scenery_available method which asks the tilemanager
if scenery for a given range around a lat/lon pair is already loaded and make
use of that method at some -9999 meter checks.
- Introduces a FGScenery::get_elevation_m method which queries the altitude at
a given position. In constrast to the groundcache functions this is the best
choice if you ask for one *single* altitude value. Make use of that thing in
AI/ATC classes and for the current views ground level. At the current views
part the groundcache is reused if possible.
- The computation of the 'current groundlevel' is no longer done on the
tilemanagers update since the required functions are now better seperated.
Alltogether it eliminates somehow redundant terrain level computations which
are now superseeded by that more finegrained functions and the existence of
the groundcache. Additionally it introduces an api to commonly required
functions which was very complex to do prevously.
Changes
=======
New volumetric shadows for FlightGear.
There is now two new checkboxes in the rendering dialog to enable/disable shadows
for the user aircraft and for static scenery objects (ie those defined in the .stg files).
AI and random objects are not handled for the moment.
known bugs
==========
- ghost objects
It happens regularly during normal operation (ufo!) and only informs about
unfortunate, but known and deliberate behavior. The user can't do anything
about it, anyway. And finally: flooding the console with this message does
only *add* to fgfs' sluggish performance and makes every other message
go unnoticed.
I have done a patch to eliminate the jitter of 3D-objects near the viewpoint
(for example 3D cockpit objects).
The problem is the roundoff accuracy of the float values used in the
scenegraph together with the transforms of the eyepoint relative to the
scenery center.
The solution will be to move the scenery center near the view point.
This way floats relative accuracy is enough to show a stable picture.
To get that right I have introduced a transform node for the scenegraph which
is responsible for that shift and uses double values as long as possible.
The scenery subsystem now has a list of all those transforms required to place
objects in the world and will tell all those transforms that the scenery
center has changed when the set_scenery_center() of the scenery subsystem is
called.
The problem was not solvable by SGModelPlacement and SGLocation, since not all
objects, especially the scenery, are placed using these classes.
The first approach was to have the scenery center exactly at the eyepoint.
This works well for the cockpit.
But then the ground jitters a bit below the aircraft. With our default views
you can't see that, but that F-18 has a camera view below the left engine
intake with the nose gear and the ground in its field of view, here I could
see that.
Having the scenery center constant will still have this roundoff problems, but
like it is now too, the roundoff error here is exactly the same in each
frame, so you will not notice any jitter.
The real solution is now to keep the scenery center constant as long as it is
in a ball of 30m radius around the view point. If the scenery center is
outside this ball, just put it at the view point.
As a sideeffect of now beeing able to switch the scenery center in the whole
scenegraph with one function call, I was able to remove a one half of a
problem when switching views, where the scenery center was far off for one or
two frames past switching from one view to the next. Also included is a fix
to the other half of this problem, where the view position was not yet copied
into a view when it is switched (at least under glut). This was responsible
for the 'Error: ...' messages of the cloud subsystem when views were
switched.
I have now split out the ground cache functions into src/FDM/groundcache.[ch]xx
Attached are the two files and the patch to integrate that cache into
FGInterface.
The code is nowhere used at the moment, the fdm's need to be updated to use
that ground cache. The JSBSim-dropin.tar.gz from Martins ftp server does this
for example.
The carrier's scenegraph is not yet processed to be visible for ground
intersection testing. So the only benefit up to now is that the api is set
up. Using this I can put the changes to make JSBSim work with that into
JSBSim's cvs. Also I aim to provide Andy a patch to make use of that with
YASim.
paging system much more robust when position change is very rapid and sporadic.
Recall that we must load 3d models in the main render thread because model
loading can trigger opengl calls (i.e. with texture loading) and all opengl
calls *must* happen in the main render thread.
To accomplish this we load the base tile in the pager thread and build a work
queue of external models that need to be loaded. We never allow a tile to be
paged out of the tile cache until all it's pending model loads are complete.
However, when changing position very rapidly, we can quickly create a huge
backlog of pending model loads because we are changing positions faster than we
can load the associated models for the existing tiles. The end result is
that tiles that are long out of range can't be removed because there is still
a huge backlog of pending model load requests and memory blows up.
This change being committed allows the tile paging system to remove tiles
if they are out of range, even when there are pending models to load. The
model loading code in the render thread can now check to see if the tile
exists and discard any model load request for tiles that no longer exist.
This situation should never occur in normal operation, but could occur in
"contrived" situations where an external script was rapidly changing
the simulator position to then be able to query FG terrain height, and doing
this for a large number of points that are distributed across a large area.
configure and compile out-of-the-box on a MinGW target:
Use -lSDL instead of -lglut32 on windows builds when --enable-sdl
is set.
Link against alut.dll in addition to openal32.dll.
Replace BSD bcopy() with ANSI C memmove() in a few places. This is
simpler than trying to abstract it out as a platform dependency in a
header file; bcopy() has never been standard.
The ENABLE_THREADS handling has changed to be set to 0 when threads
are not in use. This breaks expressions like #ifdef ENABLE_THREADS.
Replace with a slightly more complicated expression. It might have
been better to fix the configure.ac script, but I didn't know how and
this whole setting is likely to go away soon anyway.
The MinGW C runtime actually does include snprintf, so only MSVC
builds (and not all WIN32 ones) need _snprintf in JSBSim/FGState.cpp
Building on a platform with no glut at all exposed some spots where
plib/pu.h was being included without a toolkit setting (it defaults to
glut). Include fg_os.hxx first.
And when still using glut, glut.h has a bizarre dependency on a
_WCHAR_T_DEFINED symbol. It it's not defined, it tries to redefine
(!!) wchar_t to disasterous effect.
The message 'Alert: catching up on tile delete queue'
comes from the fact that 48 tiles are scheduled and
added to the cache at startup before the plane location
is initialized. My proposed patch is to initialize
SGLocation with an invalid position and detect this
fact before scheduling tiles. I prefer to do that
rather than testing for lon and lat being 0,0 because
it is a valid position and someone could want to fly
near Accra.
account for variation in lighting alignment, but it's more useful than the
previous attempt which was based on a misunderstanding of how environment
mapping worked.
are cosmetic, but we now have a combination of code that seems to work
very robustly. I was able to land the yf23 at about 130 kts on the lower
level of the bay bridge and then taxi the entire length.
from the rest of the runway lighting. VASI/PAPI lights are generally
always on. Also, the red/white VASI coloring has never worked right.
This is also a step towards fixing that problem.
This patch is there to correct a problem that prevent to load static objects when specifying a relative fg-root or a different, relative, fg-scenery. It appears that there is a mix between fg-root, fg-scenery and PLIB's model-dir.
It has been reported on the list that users are not able to see the buildings, especially those running the win32 builds because they run 'runfgfs.bat' that set FG_ROOT=./DATA.
I decided not to use model-dir because it just add confusion and to build a valid path earlier.
scene management code and organizing it within simgear. My strategy is
to identify the code I want to move, and break it's direct flightgear
dependencies. Then it will be free to move over into the simgear package.
- Moved some property specific code into simgear/props/
- Split out the condition code from fgfs/src/Main/fg_props and put it
in it's own source file in simgear/props/
- Created a scene subdirectory for scenery, model, and material property
related code.
- Moved location.[ch]xx into simgear/scene/model/
- The location and condition code had dependencies on flightgear's global
state (all the globals-> stuff, the flightgear property tree, etc.) SimGear
code can't depend on it so that data has to be passed as parameters to the
functions/methods/constructors.
- This need to pass data as function parameters had a dramatic cascading
effect throughout the FlightGear code.
a tile boundary. (Potentially imposes a slight performance penalty, but
getting the correct answer needs to be higher priority than getting the
wrong answer really quickly.)
are now working. A runway light is defined by a point and a direction. The
point and direction are combined with the local up vector to create a small
triangle orthogonal to the direction. The two ficticous corners of the
triangle are given an alpha value of zero, the orignal corner is given an
alpha of one. The triangle is drawn in glPolygonMode(GL_FRONT, GL_POINT)
mode which means only the corner points are drawn, and since two have alpha=0
only the original point is drawn. This is a long way to go to draw a point,
but it ensures that the point is only visible within 90 degrees of the light
direction, behind the light it is not visible. This is still a long way
to get to drawing a point, but we use an environement map, with the direction
vector as the normal to mimic a light that is brightest when viewed head
on and dimmest when viewed perpendicularly or disappears when viewed from
behind.
- warning, there is a bug in how the current runway light direction vector
is calculated which will adversely effect runway lighting. The airports
should be regenerated in order to fix this problem.
fgLoad3DModel() throws an exception if it fails to load the requested model.
This causes FGTileMgr::update(...) to exit. So I've added a try/catch block
to catch the exception and display an error message instead.
Animations are now contained within the scene graph itself and are
updated whenever the graph is traversed -- that saves time by not
updating animations not currently in sight, and it allows animations
to be used for static objects and random objects as well.
Added new FGModelLoader and FGTextureLoader classes. These are intern
tables for models, to guarantee (mostly) that no model is loaded more
than once. FGTextureLoader is not yet used anywhere, but
FGModelLoader is now in place everywhere that ssgLoad* used to be
used (thus adding the ability to use animations).
In the future, FGModelLoader will add some interesting functionality,
including the ability to reload 3D models on the fly.
the tile cache it's ssg elements are disconnected from the main ssg scene
graph, and then the tile is thrown on the end of a delete queue. The
tilemgr->update() routine runs every frame. It looks at this queue and if
it is non-empty, it incrementally frees the compents of the first tile
on the queue. When the tile is completely free it is removed from the queue.
The amount of time to free the memory for even a single tile can be quite
substantial, especially with the increased overhead of dynamic/random
ground objects. This change allows the system to spread the work of freeing
tile memory out over many frames so you don't get a noticable single frame
hit or stutter.
This is a small fix for what turned out to be a major bug. Ground elevation
was calculated incorrectly when distant from one of the view locations. This
resulted in several problems including bizarre gear trimming, mid air
"crashes" (as in thinking we hit the ground) and so on when close to or on the
ground.
Unfortunately it does require a second ssg traversal when in tower view
(only), but the increased load isn't all that noticable. For the time being
this really is the best solution. In a future update I will be eliminating
the unecessary per frame traversals for the static views (without having to
maintain multiple ssgRoots).
When we go to multiple FDM instances we will perhaps need to put the ssg
traversal and ground elevation queries for the FDMs into an event timer that
updates the FDMs ground elevation in a round robin fashion (maybe every 1/n
seconds where n is the number of FDM instances running).
This is a new improved patch for the previous tile manager fixes.
Rather than building dependencies between FGlocation or the viewer or fdm with
tilemgr what I ended up doing was linking the pieces together in the Mainloop
in main.cxx. You'll see what I mean...it's been commented fairly well. More
than likely we should move that chunk somewhere...just not sure where yet.
The changes seem clean now. As I get more ideas there could be some further
improvement in organizing the update in tilemgr. You'll note that I left an
override in there for the tilemgr::update() function to preserve earlier
functionality if someone needs it (e.g. usage independent of an fdm or
viewer), not to mention there are a few places in flightgear that call it
directly that have not been changed to the new interface (and may not need to be).
The code has been optimized to avoid duplicate traversals and seems to run
generally quite well. Note that there can be a short delay reloading tiles
that have been dropped from static views. We could call the tile scheduler on
a view switch, but it's not a big deal and at the moment I'd like to get this
in so people can try it and comment on it as it is.
Everything has been resycned with CVS tonight and I've included the
description submitted earlier (below).
Best,
Jim
Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates).
Files:
http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz
or
http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz
Description:
In a nutshell, these patches begin to take what was one value for ground
elevation and calculate ground elevation values seperately for the FDM and the
viewer (eye position). Several outstanding view related bugs have been fixed.
With the introduction of the new viewer code a lot of that Flight Gear code
broke related to use of a global variable called "scenery.cur_elev".
Therefore the ground_elevation and other associated items (like the current
tile bucket) is maintained per FDM instance and per View. Each of these has a
"point" or location that can be identified. See changes to FGLocation class
and main.cxx.
Most of the problems related to the new viewer in terms of sky, ground and
runway lights, and tower views are fixed.
There are four minor problems remaining. 1) The sun/moon spins when you pan
the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet
full speed with max visibility), there is a memory leak in the tile caching
that was not introduced with these changes. 3) I have not tested these
changes or made corrections to the ADA or External FDM interfaces. 4) The
change view function doesn't call the time/light update (not a problem unless
a tower is very far away).
Details:
FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's
location data can be accessed for runway (ground elevation under aircraft)
elevation.
FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now.
Commented out function that is causing a namespace conflict, hasn't been
called with recent code anyway.
FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from
FGInterface now.
Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based
(oldest tiles discard).
Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed
rendering to reference viewer altitude in order to fix a problem with ground
and runway lights.
Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for
multiple locations. Refresh function added in order to periodically make
the tiles current for a non-moving view (like a tower).
Main/fg_init.cxx - register event for making tiles current in a non-moving
view (like a tower).
Main/location.hxx - added support for current ground elevation data.
Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer
position data was required for correct sky rendering.
Main/options.cxx - fixed segfault reported by Curtis when using --view-offset
command line parameter.
Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous
bugs that were causing eye and target values to get mixed up.
graph as the terrain, except for internal cockpit view. The SSG
scene-graph variables (except for the lighting root -- I'll get that
later) are now held in globals.hxx.
FGModelMgr::draw() is obsolete; I'll remove it in a future revision.
Description:
This update includes the new viewer interface as proposed by David M. and
a first pass at cleaning up the viewer/view manager code by Jim W.
Note that I have dropped Main/viewer_lookat.?xx and Main/viewer_rph.?xx and
modified the Makefile.am accordingly.
Detail of work:
Overall:
The code reads a little easier. There are still some unnecessary bits in
there and I'd like to supplement the comments in the viewer.hxx with a tiny
bit on each interface group and what the groupings mean (similar but briefer
than what you emailed me the other day). I tried not to mess up the style,
but there is an occasional inconsistency. In general I wouldn't call it done
(especially since there's no tower yet! :)), but I'd like to get this out
there so others can comment, and test.
In Viewer:
The interface as you suggested has been implemented. Basically everything
seems to work as it did visually. There is no difference that I can see in
performance, although some things might be a tiny bit faster.
I've merged the lookat and rph (pilot view) code into the recalc for the
viewer. There is still some redundancy between the two, but a lot has been
removed. In some cases I've taken some code that we'd likely want to inline
anyway and left it in there in duplicate. You'll see that the code for both
looks a little cleaner. I need to take a closer look at the rotations in
particular. I've cleaned up a little there, but I suspect more can be done
to streamline this.
The external declaration to the Quat_mat in mouse.cxx has been removed. IMHO
the quat doesn't serve any intrinsic purpose in mouse.cxx, but I'm not about
to rip it out. It would seem that there more conventional ways to get
spherical data that are just as fast. In any case all the viewer was pulling
from the quat matrix was the pitch value so I modified mouse.cxx to output to
our pitchOffset input and that works fine.
I've changed the native values to degrees from radians where appropriate.
This required a conversion from degrees to radians in a couple modules that
access the interface. Perhaps we should add interface calls that do the
conversion, e.g. a getHeadingOffset_rad() to go along with the
getHeadingOffset_deg().
On the view_offset (now headingOffset) thing there are two entry points
because of the ability to instantly switch views or to scroll to a new view
angle (by hitting the numeric keys for example). This leaves an anomaly in
the interface which should be resolved by adding "goal" settings to the
interface, e.g. a setGoalHeadingOffset_deg(), setGoalPitchOffset_deg(), etc.
Other than these two issues, the next step here will be to look at some
further optimizations, and to write support code for a tower view. That
should be fairly simple at this point. I was considering creating a
"simulated tower view" or "pedestrian view" that defaulted to a position off
to the right of whereever the plane is at the moment you switch to the tower
view. This could be a fall back when we don't have an actual tower location
at hand (as would be the case with rural airports).
ViewManager:
Basically all I did here was neaten things up by ripping out excess crap and
made it compatible as is with the new interface.
The result is that viewmanager is now ready to be developed. The two
preexisting views are still hardcoded into the view manager. The next step
would be to design configuration xml (eg /sim/view[x]/config/blahblah) that
could be used to set up as many views as we want. If we want to take the easy
way out, we might want to insist that view[0] be a pilot-view and have
viewmanager check for that.
separate header file. This change will help integrate properties into
JSBSim.
Also, I (David Megginson) removed most of the SimGear include
statements from globals.hxx, reducing the amount of recompilation
every time SimGear changes. This required making minor changes to a
lot of files that were depending on the side-effects of the inclusions
in globals.hxx.
Added two new properties:
/environment/temperature-sea-level-degc
/environment/pressure-sea-level-inhg
These are now supported in FGEnvironment as well, though they always
have the same value for now. They need to be hooked up to the FDMs.
different locations, and hitched it into FGGlobals. FGEnvironmentMgr
has taken over as the subsystem, while FGEnvironment is simple the
information that it returns. I've removed current_environment
completely -- everything now uses properties or goes through
FGGlobals. FGGlobals itself has a couple of useful methods:
const FGEnvironment * get_environment ();
const FGEnvironment * get_environment (double lat, double lon, double alt);
The first one returns the environment data for the plane's current
position, while the second returns the environment data for any
arbitrary location. Currently, they both return the same information,
but that will change soon.