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