Further work on cleaning up SceneView and Camera, in particular moving strereo
support out of Camera and into SceneView. Also enabled the option to set the projection and modelview matrices directly on SceneView thereby removing the dependance on osg::Camrea to control the view of the scene.
This commit is contained in:
@@ -30,9 +30,6 @@ Camera::Camera(DisplaySettings* ds)
|
||||
|
||||
_useNearAndFarClippingPlanes = false;
|
||||
|
||||
_useEyeOffset = false;
|
||||
_eyeOffset.set(0.0f,0.0f,0.0f);
|
||||
|
||||
_attachedTransformMode = NO_ATTACHED_TRANSFORM;
|
||||
|
||||
if (ds) _screenDistance = ds->getScreenDistance();
|
||||
@@ -86,21 +83,14 @@ void Camera::copy(const Camera& camera)
|
||||
_eyeToModelTransform = camera._eyeToModelTransform;
|
||||
_modelToEyeTransform = camera._modelToEyeTransform;
|
||||
|
||||
// flags to determine if near and far clipping planes are required.
|
||||
_useNearAndFarClippingPlanes = camera._useNearAndFarClippingPlanes;
|
||||
|
||||
// cached matrix and clipping volume derived from above settings.
|
||||
_dirty = false;// camera._dirty;
|
||||
_projectionMatrix = NULL; //camera._projectionMatrix;
|
||||
_modelViewMatrix = NULL; //camera._modelViewMatrix;
|
||||
_clippingVolume = camera._clippingVolume;
|
||||
|
||||
_mp = NULL;
|
||||
_inversemp = NULL;
|
||||
|
||||
_useEyeOffset = camera._useEyeOffset;
|
||||
_eyeOffset = camera._eyeOffset;
|
||||
|
||||
_screenDistance = camera._screenDistance;
|
||||
_fusionDistanceMode = camera._fusionDistanceMode;
|
||||
_fusionDistanceRatio = camera._fusionDistanceRatio;
|
||||
@@ -337,7 +327,7 @@ const double Camera::calc_aspectRatio() const
|
||||
|
||||
const Matrix& Camera::getProjectionMatrix() const
|
||||
{
|
||||
if (_dirty) calculateMatricesAndClippingVolume();
|
||||
if (_dirty) computeMatrices();
|
||||
return *_projectionMatrix;
|
||||
}
|
||||
|
||||
@@ -582,25 +572,10 @@ const Vec3 Camera::getSideVector_Model() const
|
||||
|
||||
const Matrix& Camera::getModelViewMatrix() const
|
||||
{
|
||||
if (_dirty) calculateMatricesAndClippingVolume();
|
||||
if (_dirty) computeMatrices();
|
||||
return *_modelViewMatrix;
|
||||
}
|
||||
|
||||
void Camera::setUseNearAndFarClippingPlanes(const bool use)
|
||||
{
|
||||
if (_useNearAndFarClippingPlanes != use)
|
||||
{
|
||||
_useNearAndFarClippingPlanes = use;
|
||||
_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
const ClippingVolume& Camera::getClippingVolume() const
|
||||
{
|
||||
if (_dirty) calculateMatricesAndClippingVolume();
|
||||
return _clippingVolume;
|
||||
}
|
||||
|
||||
const float Camera::getFusionDistance() const
|
||||
{
|
||||
switch(_fusionDistanceMode)
|
||||
@@ -611,7 +586,7 @@ const float Camera::getFusionDistance() const
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::calculateMatricesAndClippingVolume() const
|
||||
void Camera::computeMatrices() const
|
||||
{
|
||||
|
||||
|
||||
@@ -620,13 +595,6 @@ void Camera::calculateMatricesAndClippingVolume() const
|
||||
float top = _top;
|
||||
float bottom = _bottom;
|
||||
|
||||
if (_useEyeOffset)
|
||||
{
|
||||
float dx = -_eyeOffset.x()*(1.0f/_screenDistance);
|
||||
left += dx;
|
||||
right += dx;
|
||||
}
|
||||
|
||||
// set up the projection matrix.
|
||||
switch(_projectionType)
|
||||
{
|
||||
@@ -722,62 +690,8 @@ void Camera::calculateMatricesAndClippingVolume() const
|
||||
break;
|
||||
}
|
||||
|
||||
if (_useEyeOffset)
|
||||
{
|
||||
(*_modelViewMatrix) = (*_modelViewMatrix) * Matrix::translate(-_eyeOffset*(getFusionDistance()/_screenDistance));
|
||||
}
|
||||
|
||||
|
||||
// _clippingVolume.clear();
|
||||
//
|
||||
// // set the clipping volume.
|
||||
// switch(_projectionType)
|
||||
// {
|
||||
// case(ORTHO):
|
||||
// case(ORTHO2D):
|
||||
// {
|
||||
// }
|
||||
// break;
|
||||
// case(FRUSTUM):
|
||||
// case(PERSPECTIVE):
|
||||
// {
|
||||
// // calculate the frustum normals, postive pointing inwards.
|
||||
// // left clipping plane
|
||||
// // note, _left,_right,_top and _bottom are already devided
|
||||
// // by _zNear so no need to take into account for normal
|
||||
// // calculations.
|
||||
// Vec3 leftNormal (1.0f,0.0f,left);
|
||||
// leftNormal.normalize();
|
||||
// _clippingVolume.add(Plane(leftNormal,0.0f));
|
||||
//
|
||||
//
|
||||
// Vec3 rightNormal (-1.0f,0.0f,-right);
|
||||
// rightNormal.normalize();
|
||||
// _clippingVolume.add(Plane(rightNormal,0.0f));
|
||||
//
|
||||
// Vec3 bottomNormal(0.0f,1.0f,bottom);
|
||||
// bottomNormal.normalize();
|
||||
// _clippingVolume.add(Plane(bottomNormal,0.0f));
|
||||
//
|
||||
// Vec3 topNormal(0.0f,-1.0f,-top);
|
||||
// topNormal.normalize();
|
||||
// _clippingVolume.add(Plane(topNormal,0.0f));
|
||||
//
|
||||
// if (_useNearClippingPlane)
|
||||
// {
|
||||
// _clippingVolume.add(Plane(0.0f,0.0f,-1.0f,-_zNear));
|
||||
// }
|
||||
//
|
||||
// if (_useFarClippingPlane)
|
||||
// {
|
||||
// _clippingVolume.add(Plane(0.0f,0.0f,1.0f,_zFar));
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
if (!_mp.valid()) _mp = osgNew Matrix;
|
||||
_mp->mult(*_modelViewMatrix,*_projectionMatrix);
|
||||
@@ -785,20 +699,9 @@ void Camera::calculateMatricesAndClippingVolume() const
|
||||
if (!_inversemp.valid()) _inversemp = osgNew Matrix;
|
||||
if (!_inversemp->invert(*_mp))
|
||||
{
|
||||
notify(WARN)<<"Warning: Camera::calculateMatricesAndClippingVolume() failed to invert _mp"<<std::endl;
|
||||
notify(WARN)<<"Warning: Camera::computeMatrices() failed to invert _mp"<<std::endl;
|
||||
}
|
||||
|
||||
// set up clipping volume.
|
||||
if (_useNearAndFarClippingPlanes)
|
||||
{
|
||||
_clippingVolume.setToUnitFrustum();
|
||||
}
|
||||
else
|
||||
{
|
||||
_clippingVolume.setToUnitFrustumWithoutNearFar();
|
||||
}
|
||||
_clippingVolume.transformProvidingInverse(*_mp);
|
||||
|
||||
|
||||
_dirty = false;
|
||||
}
|
||||
@@ -846,16 +749,3 @@ const bool Camera::unproject(const Vec3& win,const Viewport& viewport,Vec3& obj)
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Camera::adjustEyeOffsetForStereo(const osg::Vec3& offset)
|
||||
{
|
||||
_useEyeOffset = true;
|
||||
_eyeOffset = offset;
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void Camera::apply(State& state)
|
||||
{
|
||||
state.applyProjectionMatrix(&getProjectionMatrix());
|
||||
state.applyModelViewMatrix(&getModelViewMatrix());
|
||||
}
|
||||
|
||||
@@ -159,20 +159,35 @@ void SceneView::cull()
|
||||
{
|
||||
|
||||
_state->reset();
|
||||
|
||||
osg::ref_ptr<osg::Matrix> projection = _projectionMatrix.get();
|
||||
osg::ref_ptr<osg::Matrix> modelview = _modelviewMatrix.get();
|
||||
|
||||
if (_camera.valid())
|
||||
{
|
||||
_camera->adjustAspectRatio(_viewport->aspectRatio());
|
||||
_camera->setScreenDistance(_displaySettings->getScreenDistance());
|
||||
|
||||
if (!projection) projection = osgNew osg::Matrix(_camera->getProjectionMatrix());
|
||||
if (!modelview) modelview = osgNew osg::Matrix(_camera->getModelViewMatrix());
|
||||
}
|
||||
|
||||
if (!projection) projection = osgNew osg::Matrix();
|
||||
if (!modelview) modelview = osgNew osg::Matrix();
|
||||
|
||||
if (_displaySettings.valid() && _displaySettings->getStereo())
|
||||
{
|
||||
|
||||
_camera->setScreenDistance(_displaySettings->getScreenDistance());
|
||||
|
||||
_cameraLeft = osgNew osg::Camera(*_camera);
|
||||
_cameraRight = osgNew osg::Camera(*_camera);
|
||||
float fusionDistance = _displaySettings->getScreenDistance();
|
||||
|
||||
if (_camera.valid())
|
||||
{
|
||||
fusionDistance = _camera->getFusionDistance();
|
||||
}
|
||||
|
||||
float iod = _displaySettings->getEyeSeperation();
|
||||
|
||||
_cameraLeft->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f));
|
||||
_cameraRight->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f));
|
||||
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());
|
||||
@@ -182,22 +197,57 @@ void SceneView::cull()
|
||||
if (!_rendergraphRight.valid()) _rendergraphRight = dynamic_cast<RenderGraph*>(_rendergraph->cloneType());
|
||||
if (!_renderStageRight.valid()) _renderStageRight = dynamic_cast<RenderStage*>(_renderStage->cloneType());
|
||||
|
||||
|
||||
// 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(_cameraLeft.get(),_cullVisitorLeft.get(),_rendergraphLeft.get(),_renderStageLeft.get());
|
||||
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(_cameraRight.get(),_cullVisitorRight.get(),_rendergraphRight.get(),_renderStageRight.get());
|
||||
cullStage(projectionRight.get(),modelviewRight.get(),_cullVisitorRight.get(),_rendergraphRight.get(),_renderStageRight.get());
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
_cullVisitor->setTraversalMask(_cullMask);
|
||||
cullStage(_camera.get(),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
|
||||
cullStage(projection.get(),modelview.get(),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
|
||||
}
|
||||
|
||||
if (_camera.valid())
|
||||
{
|
||||
_camera->setNearFar(_near_plane,_far_plane);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor, osgUtil::RenderGraph* rendergraph, osgUtil::RenderStage* renderStage)
|
||||
void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil::CullVisitor* cullVisitor, osgUtil::RenderGraph* rendergraph, osgUtil::RenderStage* renderStage)
|
||||
{
|
||||
|
||||
if (!_sceneData || !_viewport->valid()) return;
|
||||
@@ -220,7 +270,6 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
|
||||
_state->setDisplaySettings(_displaySettings.get());
|
||||
|
||||
|
||||
camera->adjustAspectRatio(_viewport->aspectRatio());
|
||||
|
||||
cullVisitor->reset();
|
||||
|
||||
@@ -232,10 +281,6 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
|
||||
cullVisitor->setTraversalNumber(_frameStamp->getFrameNumber());
|
||||
}
|
||||
|
||||
// get the camera's modelview
|
||||
osg::Matrix* projection = osgNew osg::Matrix(camera->getProjectionMatrix());
|
||||
osg::Matrix* modelview = osgNew osg::Matrix(camera->getModelViewMatrix());
|
||||
|
||||
cullVisitor->setLODBias(_lodBias);
|
||||
cullVisitor->setEarthSky(NULL); // reset earth sky on each frame.
|
||||
|
||||
@@ -340,7 +385,6 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
|
||||
_far_plane = 1000.0f;
|
||||
}
|
||||
|
||||
camera->setNearFar(_near_plane,_far_plane);
|
||||
}
|
||||
|
||||
// prune out any empty RenderGraph children.
|
||||
@@ -352,14 +396,13 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SceneView::draw()
|
||||
{
|
||||
|
||||
if (_displaySettings.valid() && _displaySettings->getStereo())
|
||||
{
|
||||
|
||||
_camera->setScreenDistance(_displaySettings->getScreenDistance());
|
||||
|
||||
switch(_displaySettings->getStereoMode())
|
||||
{
|
||||
case(osg::DisplaySettings::QUAD_BUFFER):
|
||||
|
||||
Reference in New Issue
Block a user