void PickVisitor::apply(osg::Camera& camera) { if (!camera.isRenderToTextureCamera()) { if (camera.getReferenceFrame()==osg::Camera::RELATIVE_RF) { if (camera.getTransformOrder()==osg::Camera::POST_MULTIPLY) { runNestedPickVisitor( camera, camera.getViewport() ? camera.getViewport() : _lastViewport.get(), _lastProjectionMatrix * camera.getProjectionMatrix(), _lastViewMatrix * camera.getViewMatrix(), _mx, _my ); } else // PRE_MULTIPLY { runNestedPickVisitor( camera, camera.getViewport() ? camera.getViewport() : _lastViewport.get(), camera.getProjectionMatrix() * _lastProjectionMatrix, camera.getViewMatrix() * _lastViewMatrix, _mx, _my ); } } else { runNestedPickVisitor( camera, camera.getViewport() ? camera.getViewport() : _lastViewport.get(), camera.getProjectionMatrix(), camera.getViewMatrix(), _mx, _my ); } } }
void ScreenMVCullVisitor::apply(osg::Camera& camera) { //std::cerr << "MVCV camera" << std::endl; // push the node's state. StateSet* node_state = camera.getStateSet(); if(node_state) pushStateSet(node_state); //#define DEBUG_CULLSETTINGS #ifdef DEBUG_CULLSETTINGS if (osg::isNotifyEnabled(osg::NOTICE)) { notify(osg::NOTICE)<<std::endl<<std::endl<<"CullVisitor, before : "; write(osg::notify(osg::NOTICE)); } #endif // Save current cull settings CullSettings saved_cull_settings(*this); #ifdef DEBUG_CULLSETTINGS if (osg::isNotifyEnabled(osg::NOTICE)) { osg::notify(osg::NOTICE)<<"CullVisitor, saved_cull_settings : "; saved_cull_settings.write(osg::notify(osg::NOTICE)); } #endif #if 1 // set cull settings from this Camera setCullSettings(camera); #ifdef DEBUG_CULLSETTINGS osg::notify(osg::NOTICE)<<"CullVisitor, after setCullSettings(camera) : "; write(osg::notify(osg::NOTICE)); #endif // inherit the settings from above inheritCullSettings(saved_cull_settings,camera.getInheritanceMask()); #ifdef DEBUG_CULLSETTINGS osg::notify(osg::NOTICE)<<"CullVisitor, after inheritCullSettings(saved_cull_settings,"<<camera.getInheritanceMask()<<") : "; write(osg::notify(osg::NOTICE)); #endif #else // activate all active cull settings from this Camera inheritCullSettings(camera); #endif // set the cull mask. unsigned int savedTraversalMask = getTraversalMask(); bool mustSetCullMask = (camera.getInheritanceMask() & osg::CullSettings::CULL_MASK) == 0; if(mustSetCullMask) setTraversalMask(camera.getCullMask()); RefMatrix& originalModelView = *getModelViewMatrix(); osg::RefMatrix* projection = 0; osg::RefMatrix* modelview = 0; if(camera.getReferenceFrame() == osg::Transform::RELATIVE_RF) { if(camera.getTransformOrder() == osg::Camera::POST_MULTIPLY) { projection = createOrReuseMatrix( *getProjectionMatrix() * camera.getProjectionMatrix()); modelview = createOrReuseMatrix( *getModelViewMatrix() * camera.getViewMatrix()); } else // pre multiply { projection = createOrReuseMatrix( camera.getProjectionMatrix() * (*getProjectionMatrix())); modelview = createOrReuseMatrix( camera.getViewMatrix() * (*getModelViewMatrix())); } } else { // an absolute reference frame projection = createOrReuseMatrix(camera.getProjectionMatrix()); modelview = createOrReuseMatrix(camera.getViewMatrix()); } if(camera.getViewport()) pushViewport(camera.getViewport()); // record previous near and far values. float previous_znear = _computed_znear; float previous_zfar = _computed_zfar; // take a copy of the current near plane candidates DistanceMatrixDrawableMap previousNearPlaneCandidateMap; previousNearPlaneCandidateMap.swap(_nearPlaneCandidateMap); _computed_znear = FLT_MAX; _computed_zfar = -FLT_MAX; pushProjectionMatrix(projection); pushModelViewMatrix(modelview,camera.getReferenceFrame()); if(camera.getRenderOrder() == osg::Camera::NESTED_RENDER) { handle_cull_callbacks_and_traverse(camera); } else { // set up lighting. // currently ignore lights in the scene graph itself.. // will do later. osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage(); // unsigned int contextID = getState() ? getState()->getContextID() : 0; // use render to texture stage. // create the render to texture stage. osg::ref_ptr<osgUtil::RenderStageCache> rsCache = dynamic_cast<osgUtil::RenderStageCache*>(camera.getRenderingCache()); if(!rsCache) { rsCache = new osgUtil::RenderStageCache; camera.setRenderingCache(rsCache.get()); } osg::ref_ptr < osgUtil::RenderStage > rtts = rsCache->getRenderStage( this); if(!rtts) { OpenThreads::ScopedLock < OpenThreads::Mutex > lock(*(camera.getDataChangeMutex())); rtts = new osgUtil::RenderStage; rsCache->setRenderStage(this,rtts.get()); rtts->setCamera(&camera); if(camera.getInheritanceMask() & DRAW_BUFFER) { // inherit draw buffer from above. rtts->setDrawBuffer(previous_stage->getDrawBuffer(), previous_stage->getDrawBufferApplyMask()); } else { rtts->setDrawBuffer(camera.getDrawBuffer()); } if(camera.getInheritanceMask() & READ_BUFFER) { // inherit read buffer from above. rtts->setReadBuffer(previous_stage->getReadBuffer(), previous_stage->getReadBufferApplyMask()); } else { rtts->setReadBuffer(camera.getReadBuffer()); } } else { // reusing render to texture stage, so need to reset it to empty it from previous frames contents. rtts->reset(); } // set up clera masks/values rtts->setClearDepth(camera.getClearDepth()); rtts->setClearAccum(camera.getClearAccum()); rtts->setClearStencil(camera.getClearStencil()); rtts->setClearMask(camera.getClearMask()); // set up the background color and clear mask. if(camera.getInheritanceMask() & CLEAR_COLOR) { rtts->setClearColor(previous_stage->getClearColor()); } else { rtts->setClearColor(camera.getClearColor()); } if(camera.getInheritanceMask() & CLEAR_MASK) { rtts->setClearMask(previous_stage->getClearMask()); } else { rtts->setClearMask(camera.getClearMask()); } // set the color mask. osg::ColorMask* colorMask = camera.getColorMask() != 0 ? camera.getColorMask() : previous_stage->getColorMask(); rtts->setColorMask(colorMask); // set up the viewport. osg::Viewport* viewport = camera.getViewport() != 0 ? camera.getViewport() : previous_stage->getViewport(); rtts->setViewport(viewport); // set up to charge the same PositionalStateContainer is the parent previous stage. osg::Matrix inheritedMVtolocalMV; inheritedMVtolocalMV.invert(originalModelView); inheritedMVtolocalMV.postMult(*getModelViewMatrix()); rtts->setInheritedPositionalStateContainerMatrix(inheritedMVtolocalMV); rtts->setInheritedPositionalStateContainer( previous_stage->getPositionalStateContainer()); // record the render bin, to be restored after creation // of the render to text osgUtil::RenderBin* previousRenderBin = getCurrentRenderBin(); // set the current renderbin to be the newly created stage. setCurrentRenderBin(rtts.get()); // traverse the subgraph { handle_cull_callbacks_and_traverse(camera); } // restore the previous renderbin. setCurrentRenderBin(previousRenderBin); if(rtts->getStateGraphList().size() == 0 && rtts->getRenderBinList().size() == 0) { // getting to this point means that all the subgraph has been // culled by small feature culling or is beyond LOD ranges. } // and the render to texture stage to the current stages // dependancy list. switch(camera.getRenderOrder()) { case osg::Camera::PRE_RENDER: getCurrentRenderBin()->getStage()->addPreRenderStage(rtts.get(), camera.getRenderOrderNum()); break; default: getCurrentRenderBin()->getStage()->addPostRenderStage( rtts.get(),camera.getRenderOrderNum()); break; } } // restore the previous model view matrix. popModelViewMatrix(); // restore the previous model view matrix. popProjectionMatrix(); // restore the original near and far values _computed_znear = previous_znear; _computed_zfar = previous_zfar; // swap back the near plane candidates previousNearPlaneCandidateMap.swap(_nearPlaneCandidateMap); if(camera.getViewport()) popViewport(); // restore the previous traversal mask settings if(mustSetCullMask) setTraversalMask(savedTraversalMask); // restore the previous cull settings setCullSettings(saved_cull_settings); // pop the node's state off the render graph stack. if(node_state) popStateSet(); }