I've accumulated some notes over time about how OSG and VPB databases works, 
and I
thought I'd share them here for others' enlightenment, and also to ask for 
corrections. I
don't guarantee this is correct, it just seems to be correct based on my 
understanding.

  Perhaps someday this might make it into some sort of OSG Terrain Guide or 
something.




Structure of a typical VirtualPlanetBuilder/OSGDEM terrain database

Root OSG file looks like:
CoordinateSystemNode: Top-level, defines ellipsoid shape of globe
        PagedLOD
                Child0:TerrainTile (lowest LOD of terrain model)
                Child1:Basename_root_L0_X0_Y0/Basename_L0_X0_Y0_subtile.osg
                        (file containing LODs that cover the same extent as 
Child 0)


A VPB TerrainTile (for example, L0_X0_Y0) looks like:
TerrainTile (lowest LOD of terrain model)
        Locator (defines Coordinate System and Transform of TerrainTile)
        ElevationLayer
                HeightFieldLayer
                        HeightField: UniqueID, Origin, X/Y Interval, 
SkirtHeight, Heights [Array]
        ColorLayer
                ImageLayer
                        file Basename_L0_X0_Y0.dds


SubTile Basename_root_L0_X0_Y0/Basename_L0_X0_Y0_subtile.osg looks like:
Group
        PagedLOD
                Child0: TerrainTile
                Child1: Basename_L1_X0_Y0_subtile.osg (Another subtile like 
this one)
        PagedLOD
                Child0: TerrainTile
                Child1: Basename_L1_X1_Y0_subtile.osg
        ...more, similar PagedLODs may exist here...


In operation, the Root OSG file is loaded by the caller. This file contains a 
TerrainTile
with Color and Elevation data, so as soon as the initial root load is complete, 
there is a
lo-resolution terrain surface visisble. OSG immediately begins cull traversal 
of this
scene graph. During cull traversal, the PagedLOD node probably discovers that 
the
currently visible child (child 0, with the TerrainTile) is insufficient LOD for 
the
current view. The only alternate LOD is Child1, which is an external file. 
PagedLOD
informs the DatabasePager to begin loading this external file and continues on 
the cull.
The load operation has a priority level that hints to the DatabasePager how 
important this
node is, allowing multiple loads to be queued according to how close each one 
is to the
viewer.

After the first cull operation is complete, a number of cull/draw cycles may 
execute while
the DatabasePager thread completes loading and possibly compiling the loaded 
data for use
in the scenegraph. During each cull operation that the loaded external child is 
not yet
available, the PagedLOD re-requests the child node to be loaded. This allows 
the priority
of the node in the queue to adjust if the viewpoint moves prior to the node 
getting loaded.

When ready, the DatabasePager inserts the loaded subgraph (see structure of
Basename_L0_X0_Y0_subtile.osg) into the scenegraph. At this point, the top 
PagedLOD is
satisfied that it has an appropriate LOD, and subsequent cull operations will 
traverse the
Child1 of the top PagedLOD Node.

Child1 itself contains a non-trivial subgraph. At the top of the subgraph are 
several
PagedLOD nodes. Each of these contains its own Child0 LOD, which is not an 
external file
but a TerrainTile complete with ElevationLayer and ColorLayer already loaded in 
and
compiled as part of the Basename_L0_X0_Y0_subtile. So, when the Root-level 
Child0
TerrainTile is replaced with the root-level Child1 external file, the
Basename_L0_X0_Y0_subtile's Child0s immediately cover the exact same visual 
extent of
terrain without any more loading delay.

As soon as the Basename_L0_X0_Y0_subtile subgraph is merged into the scenegraph 
and
traversed by cull, the PagedLODs in L0_X0_Y0 will evaluate their LOD criteria 
(typically
expressed not as actual distance, but in realtive-apparent-size-on-screen) and 
most likely
discover they too, are insufficient for the current view. At this point, each 
of the
PagedLODs will decide to load their next LOD child (Child1). Because each of 
these
children will be located at different locations with respect to the viewer, 
they will each
individually determine a different priority, which the DatabasePager will 
respect when
queuing the DatabaseRequest.

PagedLOD class has several conditions. The base LOD class and the Group class 
beneath that
require that the container (a std::vector) that contains the actual LODs must be
contiguous – no empty slots are permitted in the container. The PagedLOD class 
defines a
parallel container called PerRangeDataList, which is also a vector holding the 
LOD ranges
and external filenames for each child that can be loaded. The contents of these 
two
containers are associated only by the subscript of their contents. What this 
means in
practice is that the LOD children in the Group must be loaded contiguously – no 
higher LOD
can be loaded if a lower LOD is not already loaded.

PagedLOD will always load LOD #0 first. If that LOD is insufficient, it will 
load #1. It
will continue loading LODs, in order, one at a time, until it reaches one that 
is
sufficient. This is because the LOD and Group classes cannot permit "gaps" in 
the
container of Group children, and the PagedLOD PerRangeDataList must load 
children into the
Group chihld slot corresponding with the PerRangeData.

VPB-created databases never have PagedLODs with more than two children. The 
first (Child
0) is always an "internal" TerrainTile that is loaded completely along with the 
PagedLOD
itself. It has a blank "external" filename in its PerRangeData (to keep the 
order of
PerRangeDataList and the Group child container in sync). The second child 
(Child1)
supplies no "internal" representation. It has an external filename that is 
loaded by the
DatabasePager.

Lower LODs are not ever unloaded because LOD class wants to be able to 
immediately switch
to a lower (and faster-performing) LOD without needing to wait for loading the 
lower LOD.
This is the conservative approach so that OSG won't have both a high-detail 
tile just
loaded, but still be showing a different, too-high-detail tile elsewhere while 
it waits
for a lower detail tile to load. Having too much unintended simultaneous detail 
loaded at
once could cause degraded redraw performance and break frame.

Child #0 cannot be unloaded or reloaded because it is not an external file. In 
order to
unload it, the actual PagedLOD it is embedded within (and possibly the file 
that PagedLOD
is contained within, which might itself contain several other PagedLODs) would 
need to be
unloaded/reloaded.



  Corrections, suggestions or comments very welcomed.

-- 
Chris 'Xenon' Hanson, omo sanza lettere                  Xenon AlphaPixel.com
PixelSense Landsat processing now available! http://www.alphapixel.com/demos/
"There is no Truth. There is only Perception. To Perceive is to Exist." - Xen
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to