Added LEFT_EYE and RIGHT_EYE stereo to osg::DisplaySettings/osgUtil::SceneView

Renamed LODBias to LODScale.
This commit is contained in:
Robert Osfield
2002-11-12 10:22:38 +00:00
parent 6d1ba6c0f4
commit 8e84722f90
15 changed files with 180 additions and 104 deletions

View File

@@ -32,19 +32,19 @@ void CollectOccludersVisitor::reset()
CullStack::reset();
}
float CollectOccludersVisitor::getDistanceToEyePoint(const Vec3& pos, bool withLODBias) const
float CollectOccludersVisitor::getDistanceToEyePoint(const Vec3& pos, bool withLODScale) const
{
if (withLODBias) return (pos-getEyeLocal()).length()*getLODBias();
if (withLODScale) return (pos-getEyeLocal()).length()*getLODScale();
else return (pos-getEyeLocal()).length();
}
float CollectOccludersVisitor::getDistanceFromEyePoint(const Vec3& pos, bool withLODBias) const
float CollectOccludersVisitor::getDistanceFromEyePoint(const Vec3& pos, bool withLODScale) const
{
const Matrix& matrix = *_modelviewStack.back();
float dist = -(pos[0]*matrix(0,2)+pos[1]*matrix(1,2)+pos[2]*matrix(2,2)+matrix(3,2));
if (withLODBias) return dist*getLODBias();
else return dist*getLODBias();
if (withLODScale) return dist*getLODScale();
else return dist*getLODScale();
}
void CollectOccludersVisitor::apply(osg::Node& node)

View File

@@ -5,7 +5,7 @@ using namespace osg;
CullStack::CullStack()
{
_cullingMode = ENABLE_ALL_CULLING;
_LODBias = 1.0f;
_LODScale = 1.0f;
_smallFeatureCullingPixelSize = 2.0f;
_frustumVolume=-1.0f;
_bbCornerNear = 0;

View File

@@ -129,6 +129,16 @@ void DisplaySettings::readEnvironmentalVariables()
{
_stereoMode = VERTICAL_SPLIT;
}
else
if (strcmp(ptr,"LEFT_EYE")==0)
{
_stereoMode = LEFT_EYE;
}
else
if (strcmp(ptr,"RIGHT_EYE")==0)
{
_stereoMode = RIGHT_EYE;
}
}
if( (ptr = getenv("OSG_STEREO")) != 0)
@@ -230,6 +240,8 @@ void DisplaySettings::readCommandLine(std::vector<std::string>& commandLine)
else if (*itr=="QUAD_BUFFER") { _stereo = true;_stereoMode = QUAD_BUFFER; ++itr; }
else if (*itr=="HORIZONTAL_SPLIT") { _stereo = true;_stereoMode = HORIZONTAL_SPLIT; ++itr; }
else if (*itr=="VERTICAL_SPLIT") { _stereo = true;_stereoMode = VERTICAL_SPLIT; ++itr; }
else if (*itr=="LEFT_EYE") { _stereo = true;_stereoMode = LEFT_EYE; ++itr; }
else if (*itr=="RIGHT_EYE") { _stereo = true;_stereoMode = RIGHT_EYE; ++itr; }
else if (*itr=="ON") { _stereo = true; ++itr; }
else if (*itr=="OFF") { _stereo = false; ++itr; }
}

View File

@@ -958,11 +958,11 @@ void Viewer::keyboard(unsigned char key, int x, int y)
break;
case '/' :
if (sceneView->getLODBias()>0.5) sceneView->setLODBias(sceneView->getLODBias()/1.5f);
if (sceneView->getLODScale()>0.5) sceneView->setLODScale(sceneView->getLODScale()/1.5f);
break;
case '*' :
if (sceneView->getLODBias()<30) sceneView->setLODBias(sceneView->getLODBias()*1.5f);
if (sceneView->getLODScale()<30) sceneView->setLODScale(sceneView->getLODScale()*1.5f);
break;
case '+' :

View File

@@ -132,9 +132,9 @@ void CullVisitor::reset()
}
float CullVisitor::getDistanceToEyePoint(const Vec3& pos, bool withLODBias) const
float CullVisitor::getDistanceToEyePoint(const Vec3& pos, bool withLODScale) const
{
if (withLODBias) return (pos-getEyeLocal()).length()*getLODBias();
if (withLODScale) return (pos-getEyeLocal()).length()*getLODScale();
else return (pos-getEyeLocal()).length();
}
@@ -143,13 +143,13 @@ inline float distance(const osg::Vec3& coord,const osg::Matrix& matrix)
return -(coord[0]*matrix(0,2)+coord[1]*matrix(1,2)+coord[2]*matrix(2,2)+matrix(3,2));
}
float CullVisitor::getDistanceFromEyePoint(const osg::Vec3& pos, bool withLODBias) const
float CullVisitor::getDistanceFromEyePoint(const osg::Vec3& pos, bool withLODScale) const
{
const Matrix& matrix = *_modelviewStack.back();
float dist = distance(pos,matrix);
if (withLODBias) return dist*getLODBias();
else return dist*getLODBias();
if (withLODScale) return dist*getLODScale();
else return dist*getLODScale();
}
void CullVisitor::popProjectionMatrix()
@@ -561,7 +561,7 @@ void CullVisitor::apply(Impostor& node)
float distance2 = (eyeLocal-bs.center()).length2();
if (!_impostorActive ||
distance2*_LODBias*_LODBias<node.getImpostorThreshold2() ||
distance2*_LODScale*_LODScale<node.getImpostorThreshold2() ||
distance2<bs.radius2()*2.0f)
{
// outwith the impostor distance threshold therefore simple

View File

@@ -24,7 +24,7 @@ SceneView::SceneView(DisplaySettings* ds)
_computeNearFar = CullVisitor::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES;
_cullingMode = osg::CullStack::ENABLE_ALL_CULLING;
_LODBias = 1.0f;
_LODScale = 1.0f;
_smallFeatureCullingPixelSize = 3.0f;
_fusionDistanceMode = USE_CAMERA_FUSION_DISTANCE;
@@ -245,6 +245,22 @@ void SceneView::cull()
if (!projection) projection = osgNew osg::Matrix();
if (!modelview) modelview = osgNew osg::Matrix();
if (!_cullVisitor)
{
osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView:: attached, creating a default CullVisitor automatically."<< std::endl;
_cullVisitor = osgNew CullVisitor;
}
if (!_rendergraph)
{
osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView:: attached, creating a global default RenderGraph automatically."<< std::endl;
_rendergraph = osgNew RenderGraph;
}
if (!_renderStage)
{
osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView::_renderStage attached, creating a default RenderStage automatically."<< std::endl;
_renderStage = osgNew RenderStage;
}
if (_displaySettings.valid() && _displaySettings->getStereo())
{
@@ -269,74 +285,114 @@ void SceneView::cull()
float sd = _displaySettings->getScreenDistance();
float es = 0.5f*iod*(fusionDistance/sd);
if (!_cullVisitorLeft.valid()) _cullVisitorLeft = dynamic_cast<CullVisitor*>(_cullVisitor->cloneType());
if (!_rendergraphLeft.valid()) _rendergraphLeft = dynamic_cast<RenderGraph*>(_rendergraph->cloneType());
if (!_renderStageLeft.valid()) _renderStageLeft = dynamic_cast<RenderStage*>(_renderStage->clone(osg::CopyOp::DEEP_COPY_ALL));
if (!_cullVisitorRight.valid()) _cullVisitorRight = dynamic_cast<CullVisitor*>(_cullVisitor->cloneType());
if (!_rendergraphRight.valid()) _rendergraphRight = dynamic_cast<RenderGraph*>(_rendergraph->cloneType());
if (!_renderStageRight.valid()) _renderStageRight = dynamic_cast<RenderStage*>(_renderStage->clone(osg::CopyOp::DEEP_COPY_ALL));
// set up the left eye.
osg::ref_ptr<osg::Matrix> projectionLeft = osgNew osg::Matrix(osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
iod/(2.0f*sd),0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f)*
(*projection));
osg::ref_ptr<osg::Matrix> modelviewLeft = osgNew osg::Matrix( (*modelview) *
osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
es,0.0f,0.0f,1.0f));
_cullVisitorLeft->setTraversalMask(_cullMaskLeft);
cullStage(projectionLeft.get(),modelviewLeft.get(),_cullVisitorLeft.get(),_rendergraphLeft.get(),_renderStageLeft.get());
// set up the right eye.
osg::ref_ptr<osg::Matrix> projectionRight = osgNew osg::Matrix(osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
-iod/(2.0f*sd),0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f)*
(*projection));
osg::ref_ptr<osg::Matrix> modelviewRight = osgNew osg::Matrix( (*modelview) *
osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
-es,0.0f,0.0f,1.0f));
_cullVisitorRight->setTraversalMask(_cullMaskRight);
cullStage(projectionRight.get(),modelviewRight.get(),_cullVisitorRight.get(),_rendergraphRight.get(),_renderStageRight.get());
if (_camera.valid() && _computeNearFar != CullVisitor::DO_NOT_COMPUTE_NEAR_FAR)
if (_displaySettings->getStereoMode()==osg::DisplaySettings::LEFT_EYE)
{
// clamp the camera to the near/far computed in cull traversal.
_camera->setNearFar(_cullVisitorRight->getCalculatedNearPlane(),_cullVisitorRight->getCalculatedFarPlane());
// set up the left eye.
osg::ref_ptr<osg::Matrix> projectionLeft = osgNew osg::Matrix(osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
iod/(2.0f*sd),0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f)*
(*projection));
osg::ref_ptr<osg::Matrix> modelviewLeft = osgNew osg::Matrix( (*modelview) *
osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
es,0.0f,0.0f,1.0f));
_cullVisitor->setTraversalMask(_cullMaskLeft);
cullStage(projectionLeft.get(),modelviewLeft.get(),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
if (_camera.valid() && _computeNearFar != CullVisitor::DO_NOT_COMPUTE_NEAR_FAR)
{
// clamp the camera to the near/far computed in cull traversal.
_camera->setNearFar(_cullVisitor->getCalculatedNearPlane(),_cullVisitor->getCalculatedFarPlane());
}
}
else if (_displaySettings->getStereoMode()==osg::DisplaySettings::RIGHT_EYE)
{
// set up the right eye.
osg::ref_ptr<osg::Matrix> projectionRight = osgNew osg::Matrix(osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
-iod/(2.0f*sd),0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f)*
(*projection));
osg::ref_ptr<osg::Matrix> modelviewRight = osgNew osg::Matrix( (*modelview) *
osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
-es,0.0f,0.0f,1.0f));
_cullVisitor->setTraversalMask(_cullMaskRight);
cullStage(projectionRight.get(),modelviewRight.get(),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
if (_camera.valid() && _computeNearFar != CullVisitor::DO_NOT_COMPUTE_NEAR_FAR)
{
// clamp the camera to the near/far computed in cull traversal.
_camera->setNearFar(_cullVisitor->getCalculatedNearPlane(),_cullVisitor->getCalculatedFarPlane());
}
}
else
{
if (!_cullVisitorLeft.valid()) _cullVisitorLeft = dynamic_cast<CullVisitor*>(_cullVisitor->cloneType());
if (!_rendergraphLeft.valid()) _rendergraphLeft = dynamic_cast<RenderGraph*>(_rendergraph->cloneType());
if (!_renderStageLeft.valid()) _renderStageLeft = dynamic_cast<RenderStage*>(_renderStage->clone(osg::CopyOp::DEEP_COPY_ALL));
if (!_cullVisitorRight.valid()) _cullVisitorRight = dynamic_cast<CullVisitor*>(_cullVisitor->cloneType());
if (!_rendergraphRight.valid()) _rendergraphRight = dynamic_cast<RenderGraph*>(_rendergraph->cloneType());
if (!_renderStageRight.valid()) _renderStageRight = dynamic_cast<RenderStage*>(_renderStage->clone(osg::CopyOp::DEEP_COPY_ALL));
// set up the left eye.
osg::ref_ptr<osg::Matrix> projectionLeft = osgNew osg::Matrix(osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
iod/(2.0f*sd),0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f)*
(*projection));
osg::ref_ptr<osg::Matrix> modelviewLeft = osgNew osg::Matrix( (*modelview) *
osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
es,0.0f,0.0f,1.0f));
_cullVisitorLeft->setTraversalMask(_cullMaskLeft);
cullStage(projectionLeft.get(),modelviewLeft.get(),_cullVisitorLeft.get(),_rendergraphLeft.get(),_renderStageLeft.get());
// set up the right eye.
osg::ref_ptr<osg::Matrix> projectionRight = osgNew osg::Matrix(osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
-iod/(2.0f*sd),0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f)*
(*projection));
osg::ref_ptr<osg::Matrix> modelviewRight = osgNew osg::Matrix( (*modelview) *
osg::Matrix(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
-es,0.0f,0.0f,1.0f));
_cullVisitorRight->setTraversalMask(_cullMaskRight);
cullStage(projectionRight.get(),modelviewRight.get(),_cullVisitorRight.get(),_rendergraphRight.get(),_renderStageRight.get());
if (_camera.valid() && _computeNearFar != CullVisitor::DO_NOT_COMPUTE_NEAR_FAR)
{
// clamp the camera to the near/far computed in cull traversal.
_camera->setNearFar(_cullVisitorRight->getCalculatedNearPlane(),_cullVisitorRight->getCalculatedFarPlane());
}
}
}
else
{
if (!_cullVisitor)
{
osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView:: attached, creating a default CullVisitor automatically."<< std::endl;
_cullVisitor = osgNew CullVisitor;
}
if (!_rendergraph)
{
osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView:: attached, creating a global default RenderGraph automatically."<< std::endl;
_rendergraph = osgNew RenderGraph;
}
if (!_renderStage)
{
osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView::_renderStage attached, creating a default RenderStage automatically."<< std::endl;
_renderStage = osgNew RenderStage;
}
_cullVisitor->setTraversalMask(_cullMask);
cullStage(projection.get(),modelview.get(),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
@@ -410,7 +466,7 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil
cullVisitor->setCullingMode(_cullingMode);
cullVisitor->setComputeNearFarMode(_computeNearFar);
cullVisitor->setLODBias(_LODBias);
cullVisitor->setLODScale(_LODScale);
cullVisitor->setSmallFeatureCullingPixelSize(_smallFeatureCullingPixelSize);
cullVisitor->setClearNode(NULL); // reset earth sky on each frame.
@@ -638,12 +694,17 @@ void SceneView::draw()
}
}
break;
case(osg::DisplaySettings::RIGHT_EYE):
case(osg::DisplaySettings::LEFT_EYE):
{
_globalState->setAttribute(_viewport.get());
_renderStage->drawPreRenderStages(*_state,previous);
_renderStage->draw(*_state,previous);
}
break;
default:
{
osg::notify(osg::NOTICE)<<"Warning: stereo camera mode not implemented yet."<< std::endl;
_globalState->setAttribute(_viewport.get());
_renderStageLeft->drawPreRenderStages(*_state,previous);
_renderStageLeft->draw(*_state,previous);
}
break;
}
@@ -651,9 +712,9 @@ void SceneView::draw()
else
{
_globalState->setAttribute(_viewport.get());
osg::ref_ptr<osg::ColorMask> cmask = osgNew osg::ColorMask;
cmask->setMask(true,true,true,true);
_globalState->setAttribute(cmask.get());
// osg::ref_ptr<osg::ColorMask> cmask = osgNew osg::ColorMask;
// cmask->setMask(true,true,true,true);
// _globalState->setAttribute(cmask.get());
// bog standard draw.
_renderStage->drawPreRenderStages(*_state,previous);