void MapNode::traverse( osg::NodeVisitor& nv ) { if ( nv.getVisitorType() == osg::NodeVisitor::EVENT_VISITOR ) { unsigned int numBlacklist = Registry::instance()->getNumBlacklistedFilenames(); if (numBlacklist != _lastNumBlacklistedFilenames) { //Only remove the blacklisted filenames if new filenames have been added since last time. _lastNumBlacklistedFilenames = numBlacklist; RemoveBlacklistedFilenamesVisitor v; //accept( v ); _terrainEngine->accept( v ); } } osg::Group::traverse( nv ); }
void LODScaleGroup::traverse(osg::NodeVisitor& nv) { if ( nv.getVisitorType() == nv.CULL_VISITOR ) { osg::CullStack* cs = dynamic_cast<osg::CullStack*>( &nv ); if ( cs ) { float lodscale = cs->getLODScale(); cs->setLODScale( lodscale * _scaleFactor ); std::for_each( _children.begin(), _children.end(), osg::NodeAcceptOp(nv)); cs->setLODScale( lodscale ); return; } } osg::Group::traverse( nv ); }
void OSGTerrainEngineNode::traverse( osg::NodeVisitor& nv ) { if ( _cull_mapf ) // ensures initialize() has been called { if ( nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR ) { // update the cull-thread map frame if necessary. (We don't need to sync the // update_mapf becuase that happens in response to a map callback.) // TODO: address the fact that this can happen from multiple threads. // Really we need a _cull_mapf PER view. -gw _cull_mapf->sync(); } } TerrainEngineNode::traverse( nv ); }
void HorizonNode::traverse(osg::NodeVisitor& nv) { bool isStealth = (VisitorData::isSet(nv, "osgEarth.Stealth")); if (nv.getVisitorType() == nv.CULL_VISITOR) { if (!isStealth) { //Horizon* h = Horizon::get(nv); osg::ref_ptr<Horizon> h = new Horizon(); osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv); osg::Vec3d eye = osg::Vec3d(0,0,0) * cv->getCurrentCamera()->getInverseViewMatrix(); h->setEye(eye); osg::Plane plane; if (h->getPlane(plane)) { osg::Quat q; q.makeRotate(osg::Plane::Vec3_type(0,0,1), plane.getNormal()); double dist = plane.distance(osg::Vec3d(0,0,0)); osg::Matrix m; m.preMultRotate(q); m.preMultTranslate(osg::Vec3d(0, 0, -dist)); m.preMultScale(osg::Vec3d(15e6, 15e6, 15e6)); setMatrix(m); } } else { osg::MatrixTransform::traverse(nv); } } else { osg::MatrixTransform::traverse(nv); } }
void ossimPlanetPointModel::traverse(osg::NodeVisitor& nv) { if(!enableFlag()||!theNode.valid()) { ossimPlanetAnnotationLayerNode::traverse(nv); return; } switch(nv.getVisitorType()) { case osg::NodeVisitor::UPDATE_VISITOR: { setRedrawFlag(false); // let's reset the redraw notification if(!theLsrSpaceTransform->model()&&layer()) theLsrSpaceTransform->setModel(layer()->model()); // if(checkPointers()) { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(thePointModelPropertyMutex); if(theNodeChangedFlag) { if(theLsrSpaceTransform->getNumChildren() > 0) { theLsrSpaceTransform->removeChildren(0, theLsrSpaceTransform->getNumChildren()); } theLsrSpaceTransform->addChild(theNode.get()); theNodeChangedFlag = false; } } break; } case osg::NodeVisitor::CULL_VISITOR: { break; } default: { break; } } theLsrSpaceTransform->accept(nv); ossimPlanetAnnotationLayerNode::traverse(nv); }
void FadeLOD::traverse( osg::NodeVisitor& nv ) { if ( nv.getVisitorType() == nv.CULL_VISITOR ) { osgUtil::CullVisitor* cv = Culling::asCullVisitor(nv); PerViewData& data = _perViewData.get(cv); if ( !data._opacity.valid() ) { data._opacity = new osg::Uniform(osg::Uniform::FLOAT, "oe_FadeLOD_opacity"); data._stateSet = new osg::StateSet(); data._stateSet->addUniform( data._opacity.get() ); } float p = cv->clampedPixelSize(getBound()) / cv->getLODScale(); float opacity; if ( p < _minPixelExtent ) opacity = 0.0f; else if ( p < _minPixelExtent + _minFadeExtent ) opacity = (p - _minPixelExtent) / _minFadeExtent; else if ( p < _maxPixelExtent - _maxFadeExtent ) opacity = 1.0f; else if ( p < _maxPixelExtent ) opacity = (_maxPixelExtent - p) / _maxFadeExtent; else opacity = 0.0f; data._opacity->set( opacity ); //OE_INFO << LC << "r = " << getBound().radius() << ", p = " << p << ", o = " << opacity << std::endl; cv->pushStateSet( data._stateSet.get() ); osg::Group::traverse( nv ); cv->popStateSet(); } else { osg::Group::traverse( nv ); } }
void MPTerrainEngineNode::traverse(osg::NodeVisitor& nv) { if ( nv.getVisitorType() == nv.CULL_VISITOR ) { // since the root tiles are manually added, the pager never has a chance to // register the PagedLODs in their children. So we have to do it manually here. if ( !_rootTilesRegistered ) { Threading::ScopedMutexLock lock(_rootTilesRegisteredMutex); if ( !_rootTilesRegistered ) { osgDB::DatabasePager* pager = dynamic_cast<osgDB::DatabasePager*>(nv.getDatabaseRequestHandler()); if ( pager ) { //OE_WARN << "Registering plods." << std::endl; pager->registerPagedLODs( _terrain ); _rootTilesRegistered = true; } } } // Inform the registry of the current frame so that Tiles have access // to the information. if ( _liveTiles.valid() && nv.getFrameStamp() ) { _liveTiles->setTraversalFrame( nv.getFrameStamp()->getFrameNumber() ); } } #if 0 static int c = 0; if ( ++c % 60 == 0 ) { OE_NOTICE << LC << "Live = " << _liveTiles->size() << ", Dead = " << _deadTiles->size() << std::endl; _liveTiles->run( CheckForOrphans() ); } #endif TerrainEngineNode::traverse( nv ); }
void Dragger::traverse(osg::NodeVisitor& nv) { if (_handleEvents && nv.getVisitorType()==osg::NodeVisitor::EVENT_VISITOR) { osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv); if (ev) { for(osgGA::EventQueue::Events::iterator itr = ev->getEvents().begin(); itr != ev->getEvents().end(); ++itr) { osgGA::GUIEventAdapter* ea = (*itr)->asGUIEventAdapter(); if (ea && handle(*ea, *(ev->getActionAdapter()))) ea->setHandled(true); } } return; } MatrixTransform::traverse(nv); }
void DOFTransform::traverse(osg::NodeVisitor& nv) { if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR) { // ensure that we do not operate on this node more than // once during this traversal. This is an issue since node // can be shared between multiple parents. if ((nv.getTraversalNumber()!=_previousTraversalNumber) && nv.getFrameStamp()) { double newTime = nv.getFrameStamp()->getSimulationTime(); animate((float)(newTime-_previousTime)); _previousTraversalNumber = nv.getTraversalNumber(); _previousTime = newTime; } } Transform::traverse(nv); }
void TileNode::traverse(osg::NodeVisitor& nv) { // Cull only: if ( nv.getVisitorType() == nv.CULL_VISITOR ) { if (_empty == false) { TerrainCuller* culler = dynamic_cast<TerrainCuller*>(&nv); if (VisitorData::isSet(culler->getParent(), "osgEarth.Stealth")) { accept_cull_stealth( culler ); } else { accept_cull( culler ); } } } // Everything else: update, GL compile, intersection, compute bound, etc. else { // If there are child nodes, traverse them: int numChildren = getNumChildren(); if ( numChildren > 0 ) { for(int i=0; i<numChildren; ++i) { _children[i]->accept( nv ); } } // Otherwise traverse the surface. else if (_surface.valid()) { _surface->accept( nv ); } } }
void VolumeTile::traverse(osg::NodeVisitor& nv) { if (!_hasBeenTraversal) { if (!_volume) { osg::NodePath& nodePath = nv.getNodePath(); if (!nodePath.empty()) { for(osg::NodePath::reverse_iterator itr = nodePath.rbegin(); itr != nodePath.rend() && !_volume; ++itr) { osgVolume::Volume* volume = dynamic_cast<Volume*>(*itr); if (volume) { OSG_INFO<<"Assigning volume system "<<volume<<std::endl; setVolume(volume); } } } } _hasBeenTraversal = true; } if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR && _layer->requiresUpdateTraversal()) { _layer->update(nv); } if (_volumeTechnique.valid()) { _volumeTechnique->traverse(nv); } else { osg::Group::traverse(nv); } }
void TileNode::traverse( osg::NodeVisitor& nv ) { if ( _model.valid() && nv.getVisitorType() == nv.CULL_VISITOR ) { osg::ClusterCullingCallback* ccc = dynamic_cast<osg::ClusterCullingCallback*>(getCullCallback()); if (ccc) { if (ccc->cull(&nv,0,static_cast<osg::State *>(0))) return; } // if this tile is marked dirty, bump the marker so the engine knows it // needs replacing. if ( _dirty || _model->_revision != _maprevision ) { _outOfDate = true; } } osg::MatrixTransform::traverse( nv ); }
void traverse( osg::NodeVisitor& nv ) { if ( _dragger.valid() ) { if ( _active && nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR ) { osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv); float pixelSize = cv->pixelSize(_dragger->getBound().center(), 0.48f); if ( pixelSize!=_draggerSize ) { float pixelScale = pixelSize>0.0f ? _draggerSize/pixelSize : 1.0f; osg::Vec3d scaleFactor(pixelScale, pixelScale, pixelScale); osg::Vec3 trans = _dragger->getMatrix().getTrans(); _dragger->setMatrix( osg::Matrix::scale(scaleFactor) * osg::Matrix::translate(trans) ); } } } osg::Group::traverse(nv); }
void SilverLiningNode::traverse(osg::NodeVisitor& nv) { if ( nv.getVisitorType() == nv.CULL_VISITOR ) { osgUtil::CullVisitor* cv = Culling::asCullVisitor(nv); osg::Camera* camera = cv->getCurrentCamera(); if ( camera ) { if(_cameraNodeMap.find(camera) == _cameraNodeMap.end()) { SilverLiningContextNode *slContextNode = new SilverLiningContextNode(this, camera, _light, _map, _options); _cameraNodeMap[camera] = slContextNode; //Use camera cull mask that will remove the need for context check //in SilverLiningContextNode, SilverLiningSkyDrawable and SilverLiningCloudsDrawable #ifdef SL_USE_CULL_MASK static int nodeMask = 0x1; slContextNode->getSLGeode()->setNodeMask(nodeMask); slContextNode->setNodeMask(nodeMask); int inheritanceMask = (osg::CullSettings::VariablesMask::ALL_VARIABLES & ~osg::CullSettings::VariablesMask::CULL_MASK); camera->setInheritanceMask(inheritanceMask); camera->setCullMask(nodeMask); nodeMask = nodeMask << 1; #endif addChild(slContextNode); } } } osgEarth::Util::SkyNode::traverse( nv ); if ( _lightSource.valid() ) { _lightSource->accept(nv); } }
void TileNode::traverse(osg::NodeVisitor& nv) { // Cull only: if ( nv.getVisitorType() == nv.CULL_VISITOR ) { osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv); if (VisitorData::isSet(nv, "osgEarth.Stealth")) { accept_cull_stealth( cv ); } else { accept_cull( cv ); } } // Everything else: update, GL compile, intersection, compute bound, etc. else { // If there are child nodes, traverse them: int numChildren = getNumChildren(); if ( numChildren > 0 ) { for(int i=0; i<numChildren; ++i) { _children[i]->accept( nv ); } } // Otherwise traverse the surface. // TODO: in what situations should we traverse the landcover as well? GL compile? else { _surface->accept( nv ); } } }
void TileGroup::traverse(osg::NodeVisitor& nv) { if ( nv.getVisitorType() == nv.CULL_VISITOR ) { // only check for update if an update isn't already in progress: if ( !_updateAgent.valid() ) { bool updateRequired = false; for( unsigned q=0; q<4; ++q) { if ( getTileNode(q)->isOutOfDate() ) { updateRequired = true; break; } } if ( updateRequired ) { // lock keeps multiple traversals from doing the same thing Threading::ScopedMutexLock exclusive( _updateMutex ); // double check to prevent a race condition: if ( !_updateAgent.valid() ) { _updateAgent = new UpdateAgent(this); } } } if ( _updateAgent.valid() ) { _updateAgent->accept( nv ); } } osg::Group::traverse( nv ); }
void Terrain::traverse(osg::NodeVisitor& nv) { if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR) { // need to check if any TerrainTechniques need to have their update called on them. osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv); if (uv) { OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); for(TerrainTileSet::iterator itr = _updateTerrainTileSet.begin(); itr != _updateTerrainTileSet.end(); ++itr) { TerrainTile* tile = *itr; tile->traverse(nv); } _updateTerrainTileSet.clear(); } } Group::traverse(nv); }
void TileNode::traverse( osg::NodeVisitor& nv ) { if ( nv.getVisitorType() == nv.CULL_VISITOR ) { osg::ClusterCullingCallback* ccc = dynamic_cast<osg::ClusterCullingCallback*>(getCullCallback()); if (ccc) { if (ccc->cull(&nv,0,static_cast<osg::State *>(0))) return; } // if this tile is marked dirty, bump the marker so the engine knows it // needs replacing. if ( _dirty || _model->_revision != _maprevision ) { _outOfDate = true; } // reset the "birth" time if necessary - this is the time at which the // node passes cull (not multi-view compatible) const osg::FrameStamp* fs = nv.getFrameStamp(); if ( fs ) { unsigned frame = fs->getFrameNumber(); if ( (frame - _lastTraversalFrame > 1) || (_bornTime == 0.0) ) { _bornTime = fs->getReferenceTime(); _bornUniform->set( (float)_bornTime ); } _lastTraversalFrame = frame; } } osg::MatrixTransform::traverse( nv ); }
void Bar::traverse(osg::NodeVisitor& nv) { if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR) { float time = nv.getFrameStamp()->getReferenceTime(); float dt = time-_time; _time = time; if (_valueptr) setValue(*_valueptr); if (_markptr) setMark(*_markptr); if (_drawmark) { // Make mark follow bar if (_markmode != STATIC && _mark < _value) { _mark = _value; _marktime = _time; } // Make mark fall after delay has run out if (_time - _marktime > _markdelay) { if (_markmode == FALL) { if (_mark > _value) _mark -= _markrate*dt; update(); } } } if (_time - _bartime > _bardelay) { if (_barmode == FALL) { if (_value > 0) _value -= _barrate*dt; if (_value < 0) _value = 0; update(); } } } }
void traverse(osg::NodeVisitor& nv) { if (nv.getVisitorType() == nv.UPDATE_VISITOR) { if ( (nv.getFrameStamp()->getFrameNumber() % 2) == 0 ) { _toggle = !_toggle; VirtualProgram* vp = VirtualProgram::getOrCreate(this->getOrCreateStateSet()); if ( _toggle ) { vp->setFunction( "make_it_red", fragShader, osgEarth::ShaderComp::LOCATION_FRAGMENT_COLORING, new Acceptor() ); } else { vp->removeShader("make_it_red"); } } } osg::Group::traverse(nv); }
void GeometryPool::traverse(osg::NodeVisitor& nv) { if (nv.getVisitorType() == nv.UPDATE_VISITOR && _releaser.valid() && _enabled) { // look for usused pool objects and push them to the resource releaser. ResourceReleaser::ObjectList objects; { Threading::ScopedMutexLock exclusive( _geometryMapMutex ); std::vector<GeometryKey> keys; for (GeometryMap::iterator i = _geometryMap.begin(); i != _geometryMap.end(); ++i) { if (i->second.get()->referenceCount() == 1) { keys.push_back(i->first); objects.push_back(i->second.get()); //OE_INFO << "Releasing: " << i->second.get() << std::endl; } } for (std::vector<GeometryKey>::iterator key = keys.begin(); key != keys.end(); ++key) { _geometryMap.erase(*key); } } if (!objects.empty()) { _releaser->push(objects); } } osg::Group::traverse(nv); }
void Page::traverse(osg::NodeVisitor& nv) { // if app traversal update the frame count. if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR) { const osg::FrameStamp* framestamp = nv.getFrameStamp(); if (framestamp) { double t = framestamp->getSimulationTime(); if (_rotation!=_targetRotation) { if (t>=_targetTime) _rotation = _targetRotation; else _rotation += (_targetRotation-_rotation)*(t-_lastTimeTraverse)/(_targetTime-_lastTimeTraverse); dirtyBound(); } _lastTimeTraverse = t; } } Transform::traverse(nv); }
void OverlayDecorator::traverse( osg::NodeVisitor& nv ) { if ( true ) //if (_totalOverlayChildren > 0 ) { // in the CULL traversal, find the per-view data associated with the // cull visitor's current camera view and work with that: if ( nv.getVisitorType() == nv.CULL_VISITOR ) { osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>( &nv ); osg::Camera* camera = cv->getCurrentCamera(); if ( camera != 0L && (_rttTraversalMask & nv.getTraversalMask()) != 0 ) { PerViewData& pvd = getPerViewData( camera ); //TODO: // check whether we need to recalculate the RTT camera params. // don't do it if the main camera hasn't moved; // also, tell the ClampingTech not to re-snap the depth texture // unless something has changed (e.g. camera params, terrain bounds..? // what about paging..?) // technique-specific setup prior to traversing: for(unsigned i=0; i<_techniques.size(); ++i) { _techniques[i]->preCullTerrain( pvd._techParams[i], cv ); } // shared terrain culling pass: cullTerrainAndCalculateRTTParams( cv, pvd ); // prep and traverse the RTT camera(s): for(unsigned i=0; i<_techniques.size(); ++i) { TechRTTParams& params = pvd._techParams[i]; _techniques[i]->cullOverlayGroup( params, cv ); } } else { osg::Group::traverse(nv); } } else { // Some other type of visitor (like update or intersection). Skip the technique // and traverse the geometry directly. for(unsigned i=0; i<_overlayGroups.size(); ++i) { _overlayGroups[i]->accept( nv ); } osg::Group::traverse( nv ); } } else { osg::Group::traverse( nv ); } }
void OverlayNode::traverse( osg::NodeVisitor& nv ) { if ( !_overlayProxyContainer.valid() ) { osg::Group::traverse( nv ); } else { if ( nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR ) { if ( _active ) { // do nothing -- culling will happen via the OverlayProxy instead. } else { // for a non-active node, just traverse children as usual. osg::Group::traverse( nv ); } } else if ( nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR ) { if ( _dirty ) { applyChanges(); _dirty = false; ADJUST_UPDATE_TRAV_COUNT( this, -1 ); } // traverse children directly, regardles of active status osg::Group::traverse( nv ); } else if (dynamic_cast<osgUtil::IntersectionVisitor*>(&nv)) { /* In order to properly intersect with overlay geometries, attempt to find the point on the terrain where the pick occurred cast a second intersector vertically at that point. Currently this is only imlpemented for our custom PrimitiveIntersector. */ osgUtil::IntersectionVisitor* iv = dynamic_cast<osgUtil::IntersectionVisitor*>(&nv); osgEarth::PrimitiveIntersector* pi = dynamic_cast<osgEarth::PrimitiveIntersector *>(iv->getIntersector()); osg::ref_ptr<MapNode> mapNode; if (pi && !pi->getOverlayIgnore() && _mapNode.lock(mapNode)) { osg::NodePath path = iv->getNodePath(); osg::NodePath prunedNodePath( path.begin(), path.end()-1 ); osg::Matrix modelToWorld = osg::computeLocalToWorld(prunedNodePath); osg::Vec3d worldStart = pi->getStart() * modelToWorld; osg::Vec3d worldEnd = pi->getEnd() * modelToWorld; osg::ref_ptr<DPLineSegmentIntersector> lsi = new DPLineSegmentIntersector(worldStart, worldEnd); osgUtil::IntersectionVisitor ivTerrain(lsi.get()); mapNode->getTerrainEngine()->accept(ivTerrain); if (lsi->containsIntersections()) { osg::Vec3d worldIntersect = lsi->getFirstIntersection().getWorldIntersectPoint(); GeoPoint mapIntersect; mapIntersect.fromWorld(mapNode->getMapSRS(), worldIntersect); osg::Vec3d newMapStart(mapIntersect.x(), mapIntersect.y(), 25000.0); osg::Vec3d newMapEnd(mapIntersect.x(), mapIntersect.y(), -25000.0); osg::Vec3d newWorldStart; mapNode->getMapSRS()->transformToWorld(newMapStart, newWorldStart); osg::Vec3d newWorldEnd; mapNode->getMapSRS()->transformToWorld(newMapEnd, newWorldEnd); osg::Matrix worldToModel; worldToModel.invert(modelToWorld); osg::Vec3d newModelStart = newWorldStart * worldToModel; osg::Vec3d newModelEnd = newWorldEnd * worldToModel; osg::ref_ptr<osgEarth::PrimitiveIntersector> pi2 = new osgEarth::PrimitiveIntersector(osgUtil::Intersector::MODEL, newModelStart, newModelEnd, pi->getThickness(), true); osgUtil::IntersectionVisitor iv2(pi2); iv2.setTraversalMask(iv->getTraversalMask()); path[0]->accept(iv2); if (pi2->containsIntersections()) { // Insert newlly found intersections into the original intersector. for (PrimitiveIntersector::Intersections::iterator it = pi2->getIntersections().begin(); it != pi2->getIntersections().end(); ++it) { PrimitiveIntersector::Intersection intersection(*it); intersection.ratio = 1.0; pi->insertIntersection(intersection); } } } else { //OE_WARN << LC << "No hits on terrain!" << std::endl; } } else { osg::Group::traverse( nv ); } } // handle other visitor types (like intersections, etc) by simply // traversing the child graph. else // if ( nv.getNodeVisitor() == osg::NodeVisitor::NODE_VISITOR ) { osg::Group::traverse( nv ); } } }
void SoundNode::traverse(osg::NodeVisitor &nv) { // continue only if the visitor actually is a cull visitor if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR) { // Make sure we only execute this once during this frame. // There could be two or more culls for stereo/multipipe... if (!m_sound_state.valid()) { // call the inherited method osg::notify(osg::DEBUG_INFO) << "SoundNode::traverse() No soundstate attached to soundnode" << std::endl; Node::traverse(nv); return; } if ( m_sound_state.valid() && nv.getTraversalNumber() != m_last_traversal_number && nv.getFrameStamp()) { m_last_traversal_number = nv.getTraversalNumber(); // retrieve the current time double t = nv.getFrameStamp()->getReferenceTime(); double time = t - m_last_time; if(time >= m_sound_manager->getUpdateFrequency()) { osg::Matrix m; m = osg::computeLocalToWorld(nv.getNodePath()); osg::Vec3 pos = m.getTrans(); m_sound_state->setPosition(pos); //Calculate velocity osg::Vec3 velocity(0,0,0); if (m_first_run) { m_first_run = false; m_last_time = t; m_last_pos = pos; } else { velocity = pos - m_last_pos; m_last_pos = pos; m_last_time = t; velocity /= time; } if(m_sound_manager->getClampVelocity()) { float max_vel = m_sound_manager->getMaxVelocity(); float len = velocity.length(); if ( len > max_vel) { velocity.normalize(); velocity *= max_vel; } } m_sound_state->setVelocity(velocity); //Get new direction osg::Vec3 dir(0,1,0); dir = dir * m; dir.normalize(); m_sound_state->setDirection(dir); // Only do occlusion calculations if the sound is playing if (m_sound_state->getPlay() && m_occlude_callback.valid()) m_occlude_callback->apply(m_sound_manager->getListenerMatrix(), pos, m_sound_state.get()); } // if } } // if cullvisitor // call the inherited method Node::traverse(nv); }
void DrapingCullSet::accept(osg::NodeVisitor& nv) { if ( nv.getVisitorType() == nv.CULL_VISITOR ) { osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>( &nv ); // We will use the visitor's path to prevent doubely-applying the statesets // of common ancestors const osg::NodePath& nvPath = nv.getNodePath(); int frame = nv.getFrameStamp() ? nv.getFrameStamp()->getFrameNumber() : 0u; for( std::vector<Entry>::iterator entry = _entries.begin(); entry != _entries.end(); ++entry ) { if ( frame - entry->_frame > 1 ) continue; // If there's an active (non-identity matrix), apply it if ( entry->_matrix.valid() ) { entry->_matrix->postMult( *cv->getModelViewMatrix() ); cv->pushModelViewMatrix( entry->_matrix.get(), osg::Transform::RELATIVE_RF ); } // After pushing the matrix, we can perform the culling bounds test. if ( !cv->isCulled( entry->_node->getBound() ) ) { // Apply the statesets in the entry's node path, but skip over the ones that are // shared with the current visitor's path since they are already in effect. // Count them so we can pop them later. int numStateSets = 0; osg::RefNodePath nodePath; if ( entry->_path.getRefNodePath(nodePath) ) { for(unsigned i=0; i<nodePath.size(); ++i) { if (nodePath[i].valid()) { if (i >= nvPath.size() || nvPath[i] != nodePath[i].get()) { osg::StateSet* stateSet = nodePath[i]->getStateSet(); if ( stateSet ) { cv->pushStateSet( stateSet ); ++numStateSets; } } } } } // Cull the DrapeableNode's children (but not the DrapeableNode itself!) // TODO: make sure we aren't skipping any cull callbacks, etc. by calling traverse // instead of accept. (Cannot call accept b/c that calls traverse) for(unsigned i=0; i<entry->_node->getNumChildren(); ++i) { entry->_node->getChild(i)->accept( nv ); } // pop the same number we pushed for(int i=0; i<numStateSets; ++i) { cv->popStateSet(); } } // pop the model view: if ( entry->_matrix.valid() ) { cv->popModelViewMatrix(); } } // mark this set so it will reset for the next frame _frameCulled = true; } else { for( std::vector<Entry>::iterator entry = _entries.begin(); entry != _entries.end(); ++entry ) { } } }
void RexTerrainEngineNode::traverse(osg::NodeVisitor& nv) { if ( nv.getVisitorType() == nv.UPDATE_VISITOR && _quickReleaseInstalled == false ) { osg::Camera* cam = findFirstParentOfType<osg::Camera>( this ); if ( cam ) { // get the installed PDC so we can nest them: osg::Camera::DrawCallback* cbToNest = cam->getPostDrawCallback(); // if it's another QR callback, we'll just replace it. QuickReleaseGLObjects* previousQR = dynamic_cast<QuickReleaseGLObjects*>(cbToNest); if ( previousQR ) cbToNest = previousQR->_next.get(); cam->setPostDrawCallback( new QuickReleaseGLObjects(_deadTiles.get(), cbToNest) ); _quickReleaseInstalled = true; OE_INFO << LC << "Quick release enabled" << std::endl; // knock down the trav count set in the constructor. ADJUST_UPDATE_TRAV_COUNT( this, -1 ); } } if ( nv.getVisitorType() == nv.CULL_VISITOR ) { // Inform the registry of the current frame so that Tiles have access // to the information. if ( _liveTiles.valid() && nv.getFrameStamp() ) { _liveTiles->setTraversalFrame( nv.getFrameStamp()->getFrameNumber() ); } } #if 0 static int c = 0; if ( ++c % 60 == 0 ) { OE_NOTICE << LC << "Live = " << _liveTiles->size() << ", Dead = " << _deadTiles->size() << std::endl; _liveTiles->run( CheckForOrphans() ); } #endif if ( _loader.valid() ) // ensures that postInitialize has run { TraversalData* tdata = TraversalData::get(nv); if ( tdata ) { RefUID& uid = tdata->getOrCreate<RefUID>("landcover.zone"); getEngineContext()->_landCoverData->_currentZoneIndex = uid; } // Pass the tile creation context to the traversal. osg::ref_ptr<osg::Referenced> data = nv.getUserData(); nv.setUserData( this->getEngineContext() ); osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv); this->getEngineContext()->startCull( cv ); TerrainEngineNode::traverse( nv ); this->getEngineContext()->endCull( cv ); if ( data.valid() ) nv.setUserData( data.get() ); } else { TerrainEngineNode::traverse( nv ); } }
void ShadowCaster::traverse(osg::NodeVisitor& nv) { if (_supported && nv.getVisitorType() == nv.CULL_VISITOR && _castingGroup->getNumChildren() > 0 && _shadowmap.valid() ) { osgUtil::CullVisitor* cv = Culling::asCullVisitor(nv); osg::Camera* camera = cv->getCurrentCamera(); if ( camera ) { osg::Matrix MV = *cv->getModelViewMatrix(); osg::Matrix inverseMV; inverseMV.invert(MV); osg::Vec3d camEye, camTo, camUp; MV.getLookAt( camEye, camTo, camUp, 1.0 ); // position the light. We only really care about the directional vector. osg::Vec4d lp4 = _light->getPosition(); osg::Vec3d lightVectorWorld( -lp4.x(), -lp4.y(), -lp4.z() ); lightVectorWorld.normalize(); osg::Vec3d lightPosWorld = osg::Vec3d(0,0,0) * inverseMV; //osg::Vec3d lightPosWorld( lp4.x(), lp4.y(), lp4.z() ); // jitter.. // construct the view matrix for the light. The up vector doesn't really // matter so we'll just use the camera's. osg::Matrix lightViewMat; osg::Vec3d lightUp(0,0,1); osg::Vec3d side = lightVectorWorld ^ lightUp; lightUp = side ^ lightVectorWorld; lightUp.normalize(); lightViewMat.makeLookAt(lightPosWorld, lightPosWorld+lightVectorWorld, lightUp); //int i = nv.getFrameStamp()->getFrameNumber() % (_ranges.size()-1); int i; for(i=0; i < (int) _ranges.size()-1; ++i) { double n = _ranges[i]; double f = _ranges[i+1]; // take the camera's projection matrix and clamp it's near and far planes // to our shadow map slice range. osg::Matrix proj = _prevProjMatrix; //cv->clampProjectionMatrix(proj, n, f); double fovy,ar,zn,zf; proj.getPerspective(fovy,ar,zn,zf); proj.makePerspective(fovy,ar,std::max(n,zn),std::min(f,zf)); // extract the corner points of the camera frustum in world space. osg::Matrix MVP = MV * proj; osg::Matrix inverseMVP; inverseMVP.invert(MVP); osgShadow::ConvexPolyhedron frustumPH; frustumPH.setToUnitFrustum(true, true); frustumPH.transform( inverseMVP, MVP ); std::vector<osg::Vec3d> verts; frustumPH.getPoints( verts ); // project those on to the plane of the light camera and fit them // to a bounding box. That box will form the extent of our orthographic camera. osg::BoundingBoxd bbox; for( std::vector<osg::Vec3d>::iterator v = verts.begin(); v != verts.end(); ++v ) bbox.expandBy( (*v) * lightViewMat ); osg::Matrix lightProjMat; n = -std::max(bbox.zMin(), bbox.zMax()); f = -std::min(bbox.zMin(), bbox.zMax()); lightProjMat.makeOrtho(bbox.xMin(), bbox.xMax(), bbox.yMin(), bbox.yMax(), n, f); // configure the RTT camera for this slice: _rttCameras[i]->setViewMatrix( lightViewMat ); _rttCameras[i]->setProjectionMatrix( lightProjMat ); // this xforms from clip [-1..1] to texture [0..1] space static osg::Matrix s_scaleBiasMat = osg::Matrix::translate(1.0,1.0,1.0) * osg::Matrix::scale(0.5,0.5,0.5); // set the texture coordinate generation matrix that the shadow // receiver will use to sample the shadow map. Doing this on the CPU // prevents nasty precision issues! osg::Matrix VPS = lightViewMat * lightProjMat * s_scaleBiasMat; _shadowMapTexGenUniform->setElement(i, inverseMV * VPS); } // install the shadow-casting traversal mask: unsigned saveMask = cv->getTraversalMask(); cv->setTraversalMask( _traversalMask & saveMask ); // render the shadow maps. cv->pushStateSet( _rttStateSet.get() ); for(i=0; i < (int) _rttCameras.size(); ++i) { _rttCameras[i]->accept( nv ); } cv->popStateSet(); // restore the previous mask cv->setTraversalMask( saveMask ); // render the shadowed subgraph. cv->pushStateSet( _renderStateSet.get() ); osg::Group::traverse( nv ); cv->popStateSet(); // save the projection matrix for the next frame. _prevProjMatrix = *cv->getProjectionMatrix(); return; } } osg::Group::traverse(nv); }
void Compositor::traverse( osg::NodeVisitor& nv ) { if ( nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR ) { osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>( &nv ); osg::RefMatrix* projectionMatrix = cv->getProjectionMatrix(); if ( _inbuiltUniforms.size()>0 ) { double fovy = 0.0, aspectRatio = 0.0, zNear = 0.0, zFar = 0.0; if ( projectionMatrix ) projectionMatrix->getPerspective( fovy, aspectRatio, zNear, zFar ); if ( _preservedZNear!=FLT_MAX ) zNear = _preservedZNear; if ( _preservedZFar!=-FLT_MAX ) zFar = _preservedZFar; for ( InbuiltUniformList::const_iterator itr=_inbuiltUniforms.begin(); itr!=_inbuiltUniforms.end(); ++itr ) { if ( !itr->second ) continue; switch ( itr->first ) { case EYE_POSITION: itr->second->set( cv->getEyeLocal() ); break; case VIEW_POINT: itr->second->set( cv->getViewPointLocal() ); break; case LOOK_VECTOR: itr->second->set( cv->getLookVectorLocal() ); break; case UP_VECTOR: itr->second->set( cv->getUpLocal() ); break; case LEFT_VECTOR: itr->second->set( cv->getLookVectorLocal() ^ cv->getUpLocal() ); break; case VIEWPORT_X: if ( cv->getViewport() ) itr->second->set( (float)cv->getViewport()->x() ); break; case VIEWPORT_Y: if ( cv->getViewport() ) itr->second->set( (float)cv->getViewport()->y() ); break; case VIEWPORT_WIDTH: if ( cv->getViewport() ) itr->second->set( (float)cv->getViewport()->width() ); break; case VIEWPORT_HEIGHT: if ( cv->getViewport() ) itr->second->set( (float)cv->getViewport()->height() ); break; case WINDOW_MATRIX: itr->second->set( osg::Matrixf(cv->getWindowMatrix()) ); break; case INV_WINDOW_MATRIX: itr->second->set( osg::Matrixf::inverse(cv->getWindowMatrix()) ); break; case FRUSTUM_NEAR_PLANE: itr->second->set( (float)zNear ); break; case FRUSTUM_FAR_PLANE: itr->second->set( (float)zFar ); break; case SCENE_FOV_IN_RADIANS: itr->second->set( (float)osg::DegreesToRadians(fovy) ); break; case SCENE_ASPECT_RATIO: itr->second->set( (float)aspectRatio ); break; case SCENE_MODELVIEW_MATRIX: if ( cv->getModelViewMatrix() ) itr->second->set( osg::Matrixf(*cv->getModelViewMatrix()) ); break; case SCENE_INV_MODELVIEW_MATRIX: if ( cv->getModelViewMatrix() ) itr->second->set( osg::Matrixf::inverse(*cv->getModelViewMatrix()) ); break; case SCENE_PROJECTION_MATRIX: if ( projectionMatrix ) itr->second->set( osg::Matrixf(*projectionMatrix) ); break; case SCENE_INV_PROJECTION_MATRIX: if ( projectionMatrix ) itr->second->set( osg::Matrixf::inverse(*projectionMatrix) ); break; default: break; } } } traverseAllPasses( nv ); return; // don't traverse as usual } if ( nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR || nv.getVisitorType()==osg::NodeVisitor::EVENT_VISITOR ) { traverseAllPasses( nv ); // just handle uniform callbacks } osg::Group::traverse( nv ); }
void PagerLoader::traverse(osg::NodeVisitor& nv) { // only called when _mergesPerFrame > 0 if ( nv.getVisitorType() == nv.UPDATE_VISITOR ) { if ( nv.getFrameStamp() ) { setFrameStamp(nv.getFrameStamp()); } int count; for(count=0; count < _mergesPerFrame && !_mergeQueue.empty(); ++count) { Request* req = _mergeQueue.begin()->get(); if ( req && req->_lastTick >= _checkpoint ) { OE_START_TIMER(req_apply); req->apply( getFrameStamp() ); double s = OE_STOP_TIMER(req_apply); req->setState(Request::FINISHED); } _mergeQueue.erase( _mergeQueue.begin() ); } // cull finished requests. { Threading::ScopedMutexLock lock( _requestsMutex ); unsigned fn = 0; if ( nv.getFrameStamp() ) fn = nv.getFrameStamp()->getFrameNumber(); // Purge expired requests. for(Requests::iterator i = _requests.begin(); i != _requests.end(); ) { Request* req = i->second.get(); if ( req->isFinished() ) { //OE_INFO << LC << req->getName() << "(" << i->second->getUID() << ") finished." << std::endl; req->setState( Request::IDLE ); if ( REPORT_ACTIVITY ) Registry::instance()->endActivity( req->getName() ); _requests.erase( i++ ); } else if ( !req->isMerging() && (fn - req->getLastFrameSubmitted() > 2) ) { //OE_INFO << LC << req->getName() << "(" << i->second->getUID() << ") died waiting after " << fn-req->getLastFrameSubmitted() << " frames" << std::endl; req->setState( Request::IDLE ); if ( REPORT_ACTIVITY ) Registry::instance()->endActivity( req->getName() ); _requests.erase( i++ ); } else // still valid. { ++i; } } //OE_NOTICE << LC << "PagerLoader: requests=" << _requests.size() << "; mergeQueue=" << _mergeQueue.size() << std::endl; } } LoaderGroup::traverse( nv ); }