// override osg::Node* createNode( ProgressCallback* progress ) { osg::ref_ptr<osg::Node> result; // required if the model includes local refs, like PagedLOD or ProxyNode: osg::ref_ptr<osgDB::Options> localOptions = Registry::instance()->cloneOrCreateOptions( _dbOptions.get() ); //_dbOptions.get() ? //new osgDB::Options(*_dbOptions.get()) : new osgDB::Options(); localOptions->getDatabasePathList().push_back( osgDB::getFilePath(_options.url()->full()) ); result = _options.url()->getNode( localOptions.get(), CachePolicy::INHERIT, progress ); //result = _options.url()->readNode( localOptions.get(), CachePolicy::NO_CACHE, progress ).releaseNode(); if (_options.location().isSet()) { GeoPoint geoPoint(_map->getProfile()->getSRS(), (*_options.location()).x(), (*_options.location()).y(), (*_options.location()).z()); OE_NOTICE << "Read location " << geoPoint.vec3d() << std::endl; osg::Matrixd matrix; geoPoint.createLocalToWorld( matrix ); if (_options.orientation().isSet()) { //Apply the rotation osg::Matrix rot_mat; rot_mat.makeRotate( osg::DegreesToRadians((*_options.orientation()).y()), osg::Vec3(1,0,0), osg::DegreesToRadians((*_options.orientation()).x()), osg::Vec3(0,0,1), osg::DegreesToRadians((*_options.orientation()).z()), osg::Vec3(0,1,0) ); matrix.preMult(rot_mat); } osg::MatrixTransform* mt = new osg::MatrixTransform; mt->setMatrix( matrix ); mt->addChild( result.get() ); result = mt; } if(_options.lodScale().isSet()) { LODScaleOverrideNode * node = new LODScaleOverrideNode; node->setLODScale(_options.lodScale().value()); node->addChild(result.release()); result = node; } return result.release(); }
// override osg::Node* createNodeImplementation(const Map* map, const osgDB::Options* dbOptions, ProgressCallback* progress ) { osg::ref_ptr<osg::Node> result; // Only support paging if they've enabled it and provided a min/max range bool usePagedLOD = *_options.paged() && (_options.minRange().isSet() || _options.maxRange().isSet()); if (_options.node() != NULL) { result = _options.node(); } else { // Only load the model if it's not paged or we don't have a location set. if (!usePagedLOD || !_options.location().isSet()) { // required if the model includes local refs, like PagedLOD or ProxyNode: osg::ref_ptr<osgDB::Options> localOptions = Registry::instance()->cloneOrCreateOptions( dbOptions ); localOptions->getDatabasePathList().push_back( osgDB::getFilePath(_options.url()->full()) ); result = _options.url()->getNode( localOptions.get(), progress ); } } // Always create a matrix transform osg::MatrixTransform* mt = new osg::MatrixTransform; if (_options.location().isSet() && map != 0L) { GeoPoint geoPoint( map->getProfile()->getSRS(), (*_options.location()).x(), (*_options.location()).y(), (*_options.location()).z(), ALTMODE_ABSOLUTE ); osg::Matrixd matrix; geoPoint.createLocalToWorld( matrix ); if (_options.orientation().isSet()) { //Apply the rotation osg::Matrix rot_mat; rot_mat.makeRotate( osg::DegreesToRadians((*_options.orientation()).y()), osg::Vec3(1,0,0), osg::DegreesToRadians((*_options.orientation()).x()), osg::Vec3(0,0,1), osg::DegreesToRadians((*_options.orientation()).z()), osg::Vec3(0,1,0) ); matrix.preMult(rot_mat); } mt->setMatrix( matrix ); } if ( _options.minRange().isSet() || _options.maxRange().isSet() ) { float minRange = _options.minRange().isSet() ? (*_options.minRange()) : 0.0f; float maxRange = _options.maxRange().isSet() ? (*_options.maxRange()) : FLT_MAX; osg::LOD* lod = 0; if (!usePagedLOD) { // Just use a regular LOD lod = new osg::LOD(); lod->addChild(result.release(), minRange, maxRange); } else { // Use a PagedLOD osg::PagedLOD* plod =new osg::PagedLOD(); plod->setFileName(0, _options.url()->full()); // If they want the model to be paged but haven't given us a location we have to load // up the node up front and figure out what it's center and radius are or it won't page in. if (!_options.location().isSet() && result.valid()) { osg::Vec3d center = result->getBound().center(); OE_DEBUG << "Radius=" << result->getBound().radius() << " center=" << center.x() << "," << center.y() << "," << center.z() << std::endl; plod->setCenter(result->getBound().center()); plod->setRadius(result->getBound().radius()); } lod = plod; } lod->setRange(0, minRange, maxRange); mt->addChild(lod); } else { // Simply add the node to the matrix transform if (result.valid()) { mt->addChild( result.get() ); } } result = mt; // generate a shader program to render the model. if ( result.valid() ) { if(_options.loadingPriorityScale().isSet() || _options.loadingPriorityOffset().isSet()) { SetLoadPriorityVisitor slpv(_options.loadingPriorityScale().value(), _options.loadingPriorityOffset().value()); result->accept(slpv); } if(_options.lodScale().isSet()) { LODScaleOverrideNode * node = new LODScaleOverrideNode; node->setLODScale(_options.lodScale().value()); node->addChild(result.release()); result = node; } if ( _options.shaderPolicy() == SHADERPOLICY_GENERATE ) { osg::ref_ptr<StateSetCache> cache = new StateSetCache(); Registry::shaderGenerator().run( result, _options.url()->base(), cache.get() ); cache->dumpStats(); } else if ( _options.shaderPolicy() == SHADERPOLICY_DISABLE ) { result->getOrCreateStateSet()->setAttributeAndModes( new osg::Program(), osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE ); } } return result.release(); }