Changeset 844

Show
Ignore:
Timestamp:
01/17/08 19:05:09
Author:
robert
Message:

Added support for ClusterCullingCallback? in --terrain/osgTerrain generated databases

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/vpb/Destination

    r843 r844  
    1616 
    1717#include <vpb/Source> 
     18#include <osg/ClusterCullingCallback> 
    1819 
    1920namespace vpb 
     
    161162    osg::Node* createTerrainTile(); 
    162163    osg::Node* createPolygonal(); 
     164     
     165    osg::ClusterCullingCallback* createClusterCullingCallback(); 
    163166 
    164167    void addSource(Source* source) { _sources.push_back(source); } 
  • trunk/src/vpb/Destination.cpp

    r843 r844  
    2020#include <osg/ShapeDrawable> 
    2121#include <osg/Geometry> 
    22 #include <osg/ClusterCullingCallback> 
    2322#include <osg/MatrixTransform> 
    2423#include <osg/Notify> 
     
    12431242} 
    12441243 
     1244osg::ClusterCullingCallback* DestinationTile::createClusterCullingCallback() 
     1245{ 
     1246    // make sure we are dealing with a geocentric database 
     1247    if (!_dataSet->mapLatLongsToXYZ()) return 0; 
     1248 
     1249    osg::HeightField* grid = _terrain.valid() ? _terrain->_heightField.get() : 0; 
     1250    if (!grid) return 0; 
     1251 
     1252    const osg::EllipsoidModel* et = _dataSet->getEllipsoidModel(); 
     1253    double globe_radius = et ? et->getRadiusPolar() : 1.0; 
     1254    unsigned int numColumns = grid->getNumColumns(); 
     1255    unsigned int numRows = grid->getNumRows(); 
     1256 
     1257 
     1258    double midLong = grid->getOrigin().x()+grid->getXInterval()*((double)(numColumns-1))*0.5; 
     1259    double midLat = grid->getOrigin().y()+grid->getYInterval()*((double)(numRows-1))*0.5; 
     1260    double midZ = grid->getOrigin().z(); 
     1261 
     1262    double midX,midY; 
     1263    et->convertLatLongHeightToXYZ(osg::DegreesToRadians(midLat),osg::DegreesToRadians(midLong),midZ, midX,midY,midZ); 
     1264 
     1265    osg::Vec3 center_position(midX,midY,midZ); 
     1266 
     1267    osg::Vec3 center_normal(midX,midY,midZ); 
     1268    center_normal.normalize(); 
     1269     
     1270    osg::Vec3 transformed_center_normal = center_normal; 
     1271 
     1272    unsigned int r,c; 
     1273     
     1274    // populate the vertex/normal/texcoord arrays from the grid. 
     1275    double orig_X = grid->getOrigin().x(); 
     1276    double delta_X = grid->getXInterval(); 
     1277    double orig_Y = grid->getOrigin().y(); 
     1278    double delta_Y = grid->getYInterval(); 
     1279    double orig_Z = grid->getOrigin().z(); 
     1280 
     1281 
     1282    float min_dot_product = 1.0f; 
     1283    float max_cluster_culling_height = 0.0f; 
     1284    float max_cluster_culling_radius = 0.0f; 
     1285 
     1286    for(r=0;r<numRows;++r) 
     1287    { 
     1288        for(c=0;c<numColumns;++c) 
     1289        { 
     1290            double X = orig_X + delta_X*(double)c; 
     1291            double Y = orig_Y + delta_Y*(double)r; 
     1292            double Z = orig_Z + grid->getHeight(c,r); 
     1293            double height = Z; 
     1294 
     1295            et->convertLatLongHeightToXYZ(osg::DegreesToRadians(Y),osg::DegreesToRadians(X),Z, 
     1296                                         X,Y,Z); 
     1297 
     1298            osg::Vec3d v(X,Y,Z); 
     1299            osg::Vec3 dv = v - center_position; 
     1300            double d = sqrt(dv.x()*dv.x() + dv.y()*dv.y() + dv.z()*dv.z()); 
     1301            double theta = acos( globe_radius/ (globe_radius + fabs(height)) ); 
     1302            double phi = 2.0 * asin (d*0.5/globe_radius); // d/globe_radius; 
     1303            double beta = theta+phi; 
     1304            double cutoff = osg::PI_2 - 0.1; 
     1305             
     1306            //log(osg::INFO,"theta="<<theta<<"\tphi="<<phi<<" beta "<<beta); 
     1307            if (phi<cutoff && beta<cutoff) 
     1308            { 
     1309 
     1310                float local_dot_product = -sin(theta + phi); 
     1311                float local_m = globe_radius*( 1.0/ cos(theta+phi) - 1.0); 
     1312                float local_radius = static_cast<float>(globe_radius * tan(beta)); // beta*globe_radius; 
     1313                min_dot_product = osg::minimum(min_dot_product, local_dot_product); 
     1314                max_cluster_culling_height = osg::maximum(max_cluster_culling_height,local_m);       
     1315                max_cluster_culling_radius = osg::maximum(max_cluster_culling_radius,local_radius); 
     1316            } 
     1317            else 
     1318            { 
     1319                //log(osg::INFO,"Turning off cluster culling for wrap around tile."); 
     1320                return 0; 
     1321            } 
     1322        } 
     1323    } 
     1324     
     1325 
     1326    // set up cluster cullling,  
     1327    osg::ClusterCullingCallback* ccc = new osg::ClusterCullingCallback; 
     1328 
     1329    ccc->set(center_position + transformed_center_normal*max_cluster_culling_height , 
     1330             transformed_center_normal,  
     1331             min_dot_product, 
     1332             max_cluster_culling_radius); 
     1333 
     1334    return ccc; 
     1335} 
     1336 
    12451337osg::Node* DestinationTile::createTerrainTile() 
    12461338{ 
    1247 #if 0 
    1248     return createHeightField(); 
    1249 #else 
    1250  
    12511339    if (!_terrain) _terrain = new DestinationData(_dataSet); 
    12521340 
     
    13341422    } 
    13351423     
    1336 #if 1 
    13371424    // assign the terrain technique that will be used to render the terrain tile. 
    13381425    osgTerrain::GeometryTechnique* gt = new osgTerrain::GeometryTechnique; 
    13391426    terrain->setTerrainTechnique(gt); 
    1340 #endif 
     1427     
     1428    // assign cluster culling callback to terrain 
     1429    terrain->setCullCallback(createClusterCullingCallback()); 
    13411430     
    13421431    return terrain; 
    1343 #endif 
    13441432} 
    13451433 
     
    20872175            readFrom(itr->get()); 
    20882176        } 
    2089         log(osg::NOTICE,"DestinationTile::readFrom(CompositeSource* ) numChecked %i",numChecked); 
     2177         
     2178        log(osg::INFO,"DestinationTile::readFrom(CompositeSource* ) numChecked %i",numChecked); 
    20902179 
    20912180        optimizeResolution(); 
     
    21022191    allocate(); 
    21032192 
    2104     log(osg::NOTICE,"DestinationTile::readFrom() %i",_sources.size()); 
     2193    log(osg::INFO,"DestinationTile::readFrom() %i",_sources.size()); 
    21052194    for(Sources::iterator itr = _sources.begin(); 
    21062195        itr != _sources.end(); 
     
    22842373    { 
    22852374        Triple(): 
    2286             _drawable(0), 
     2375            _object(0), 
    22872376            _callback(0) {} 
    22882377     
    2289         Triple(osg::NodePath nodePath, osg::Drawable* drawable, osg::ClusterCullingCallback* callback): 
     2378        Triple(osg::NodePath nodePath, osg::Object* object, osg::ClusterCullingCallback* callback): 
    22902379            _nodePath(nodePath), 
    2291             _drawable(drawable), 
     2380            _object(object), 
    22922381            _callback(callback) {} 
    22932382 
    22942383        Triple(const Triple& t): 
    22952384            _nodePath(t._nodePath), 
    2296             _drawable(t._drawable), 
     2385            _object(t._object), 
    22972386            _callback(t._callback) {} 
    22982387 
     
    23002389        { 
    23012390            _nodePath = t._nodePath; 
    2302             _drawable = t._drawable
     2391            _object = t._object
    23032392            _callback = t._callback; 
    23042393            return *this; 
     
    23062395 
    23072396        osg::NodePath                   _nodePath; 
    2308         osg::Drawable*                  _drawable
     2397        osg::Object*                    _object
    23092398        osg::ClusterCullingCallback*    _callback; 
    23102399    }; 
     
    23172406    virtual void apply(osg::Group& group) 
    23182407    { 
    2319         if (dynamic_cast<osgTerrain::Terrain*>(&group)==0) 
     2408        osgTerrain::Terrain* terrain = dynamic_cast<osgTerrain::Terrain*>(&group); 
     2409        if (terrain) 
     2410        { 
     2411            osg::ClusterCullingCallback* callback = dynamic_cast<osg::ClusterCullingCallback*>(terrain->getCullCallback()); 
     2412            if (callback)  
     2413            { 
     2414                _callbackList.push_back(Triple(getNodePath(),terrain,callback)); 
     2415            } 
     2416        } 
     2417        else 
    23202418        { 
    23212419            osg::NodeVisitor::apply(group); 
     
    24632561                 
    24642562                // remove it from the drawable. 
    2465                 triple._drawable->setCullCallback(0); 
     2563                 
     2564                osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(triple._object); 
     2565                if (drawable) drawable->setCullCallback(0); 
     2566 
     2567                osg::Node* node = dynamic_cast<osg::Node*>(triple._object); 
     2568                if (node) node->setCullCallback(0); 
    24662569            } 
    24672570        } 
     
    26842787                pagedLOD->setCullCallback(triple._callback); 
    26852788                 
    2686                 // remove it from the drawable. 
    2687                 triple._drawable->setCullCallback(0); 
     2789                osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(triple._object); 
     2790                if (drawable) drawable->setCullCallback(0); 
     2791 
     2792                osg::Node* node = dynamic_cast<osg::Node*>(triple._object); 
     2793                if (node) node->setCullCallback(0); 
    26882794            } 
    26892795        }