OSG立體模式下動態修改相機遠近裁剪面的實現
1. 非立體模式下動態修改相機遠近裁剪面
class GLB_DLLCLASS_EXPORT CGlbGlobeClipHandler : public osg::NodeCallback
{
struct CustomProjClamper : public osg::CullSettings::ClampProjectionMatrixCallback
{
template<class matrix_type, class value_type>
bool _clampProjectionMatrix(matrix_type& projection, double& znear, double& zfar, value_type nearFarRatio) const
{....}
...........
}
}
mpr_cliphandler = new CGlbGlobeClipHandler(p_globe);
mpr_p_root->setUpdateCallback((osg::NodeCallback*)mpr_cliphandler);
在根節點回調中mpr_cliphandler計算CustomProjClamper的成員變量double _nearFarRatio的值,然後在_clampProjectionMatrix中使用它來計算最遠最近裁剪面.
osg::ref_ptr<osg::CullSettings::ClampProjectionMatrixCallback> clamper = new CGlbGlobeClipHandler::CustomProjClamper();
mpr_cliphandler->mpr_p_clampers[mpr_osgviewer->getCamera()] = clamper;
mpr_osgviewer->getCamera()->setClampProjectionMatrixCallback(clamper.get());
2. 立體模式下動態修改相機遠近裁剪面
在osg3.2.1版本上測試發現,紅綠立體模式、Quad_Buffer立體模式下以上代碼不起作用,不能動態修改遠近裁剪面 。
追蹤源代碼發現在 osgUtil的SceneView類 void SceneView::cull()中以下代碼
_cullVisitorLeft->setDatabaseRequestHandler(_cullVisitor->getDatabaseRequestHandler());
_cullVisitorLeft->setClampProjectionMatrixCallback(_cullVisitor->getClampProjectionMatrixCallback());
_cullVisitorLeft->setTraversalMask(_cullMaskLeft);
computeLeftEyeViewport(getViewport());
bool computeNearFar = cullStage(computeLeftEyeProjection(getProjectionMatrix()),computeLeftEyeView(getViewMatrix()),_cullVisitorLeft.get(),_stateGraphLeft.get(),_renderStageLeft.get(),_viewportLeft.get());
// set up the right eye.
_cullVisitorRight->setDatabaseRequestHandler(_cullVisitor->getDatabaseRequestHandler());
_cullVisitorRight->setClampProjectionMatrixCallback(_cullVisitor->getClampProjectionMatrixCallback());
_cullVisitorRight->setTraversalMask(_cullMaskRight);
computeRightEyeViewport(getViewport());
computeNearFar = cullStage(computeRightEyeProjection(getProjectionMatrix()),computeRightEyeView(getViewMatrix()),_cullVisitorRight.get(),_stateGraphRight.get(),_renderStageRight.get(),_viewportRight.get());
if (computeNearFar)
{
CullVisitor::value_type zNear = osg::minimum(_cullVisitorLeft->getCalculatedNearPlane(),_cullVisitorRight->getCalculatedNearPlane());
CullVisitor::value_type zFar = osg::maximum(_cullVisitorLeft->getCalculatedFarPlane(),_cullVisitorRight->getCalculatedFarPlane());
_cullVisitor->clampProjectionMatrix(getProjectionMatrix(),zNear,zFar);
}
跟蹤發現_cullVisitor中的_clampProjectionMatrixCallback對象為空,說明對主camera設置ClampProjectionMatrixCallback不能影響到_cullVisitor的_clampProjectionMatrixCallback。
這樣解決辦法就出來了,將主camera用到的ClampProjectionMatrixCallback對象設置一份給_cullVisitor就可以了!!!!!!!!!!
經測試通過,方法可行............................OK
OSG立體模式下動態修改相機遠近裁剪面的實現