diff --git a/include/osg/Camera b/include/osg/Camera index 333fd7981..424908f4b 100644 --- a/include/osg/Camera +++ b/include/osg/Camera @@ -242,17 +242,6 @@ class SG_EXPORT Camera: public osg::Referenced * equivalent to using gluLookAt.*/ const Matrix& getModelViewMatrix() const; - - /** Switch on/off the use of the near and far clipping plane which creating the - * getClippingVolume(), uses the camera _zfar value for the position - * of the far clipping plane. By default this value is off.*/ - void setUseNearAndFarClippingPlanes(const bool use); - /** Get whether the ClippingVolume uses a near and far clipping planes.*/ - const bool getUseNearAndFarClippingPlanes() const { return _useNearAndFarClippingPlanes; } - - /** get the view frustum clipping in model coordinates */ - const ClippingVolume& getClippingVolume() const; - /** Map object coordinates into windows coordinates. * Equivalent to gluProject(...). */ @@ -297,15 +286,6 @@ class SG_EXPORT Camera: public osg::Referenced /** Get the physical distance between the viewers eyes and the display system.*/ const float getScreenDistance() const { return _screenDistance; } - /** Convinience method for adjusting the project and model view to account for - * and eye offset, as used in stereo work, assumes that the users will use - * a seperate camera for each eye, adjustEyePointForStereo(..) being used to - * specialize the camera for each eye view.*/ - void adjustEyeOffsetForStereo(const osg::Vec3& offset); - - - /** Set up the OpenGL projection and model view matrices.*/ - virtual void apply(State& state); protected: @@ -352,11 +332,8 @@ class SG_EXPORT Camera: public osg::Referenced mutable ref_ptr _mp; mutable ref_ptr _inversemp; - void calculateMatricesAndClippingVolume() const; + void computeMatrices() const; - // used for offsetting camera to ajust for left and right stereo views. - bool _useEyeOffset; - osg::Vec3 _eyeOffset; float _screenDistance; FusionDistanceMode _fusionDistanceMode; diff --git a/include/osg/ImpostorSprite b/include/osg/ImpostorSprite index 1fb42e9e1..dc604dc94 100644 --- a/include/osg/ImpostorSprite +++ b/include/osg/ImpostorSprite @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/include/osg/State b/include/osg/State index 61acebfef..426f4a213 100644 --- a/include/osg/State +++ b/include/osg/State @@ -10,8 +10,8 @@ #include #include -#include #include +#include #include #include diff --git a/include/osgUtil/SceneView b/include/osgUtil/SceneView index 39597a842..f22fbc3d1 100644 --- a/include/osgUtil/SceneView +++ b/include/osgUtil/SceneView @@ -115,14 +115,22 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced osg::State* getState() { return _state.get(); } const osg::State* getState() const { return _state.get(); } + + /** set an osg::Camera for the scene view to use for setting projection and modelview matrices internaly. + * However, the projection matrix from the camera will be overriden by a projection matrix which is set explicitly + * via setProjectionMatrix(..), see below. + * Also, the model matrix from the camera will be overriden by a modelview matrix which is set explicitly + * via setModelViewMatrix(..), see below.*/ void setCamera(osg::Camera* camera) { _camera = camera; } osg::Camera* getCamera() { return _camera.get(); } const osg::Camera* getCamera() const { return _camera.get(); } + /** set an projection matrix. Note, this will override a camera's projection matrix if it is not NULL.*/ void setProjectionMatrix(osg::Matrix* matrix) { _projectionMatrix = matrix; } osg::Matrix* getProjectionMatrix() { return _projectionMatrix.get(); } const osg::Matrix* getProjectionMatrix() const { return _projectionMatrix.get(); } + /** set an modelview matrix. Note, this will override a camera's modelview matrix if it is not NULL.*/ void setModelViewMatrix(osg::Matrix* matrix) { _modelviewMatrix = matrix; } osg::Matrix* getModelViewMatrix() { return _modelviewMatrix.get(); } const osg::Matrix* getModelViewMatrix() const { return _modelviewMatrix.get(); } @@ -237,7 +245,7 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced virtual ~SceneView(); /** Do cull traversal of attached scene graph using Cull NodeVisitor.*/ - virtual void cullStage(osg::Camera* camera,osgUtil::CullVisitor* cullVisitor, osgUtil::RenderGraph* rendergraph, osgUtil::RenderStage* renderStage); + virtual void cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil::CullVisitor* cullVisitor, osgUtil::RenderGraph* rendergraph, osgUtil::RenderStage* renderStage); virtual void drawStage(osgUtil::RenderStage* renderStage); osg::ref_ptr _sceneData; @@ -258,13 +266,11 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced osg::ref_ptr _renderStage; osg::Node::NodeMask _cullMaskLeft; - osg::ref_ptr _cameraLeft; osg::ref_ptr _cullVisitorLeft; osg::ref_ptr _rendergraphLeft; osg::ref_ptr _renderStageLeft; osg::Node::NodeMask _cullMaskRight; - osg::ref_ptr _cameraRight; osg::ref_ptr _cullVisitorRight; osg::ref_ptr _rendergraphRight; osg::ref_ptr _renderStageRight; diff --git a/src/osg/Camera.cpp b/src/osg/Camera.cpp index e2d89454d..d876546c9 100644 --- a/src/osg/Camera.cpp +++ b/src/osg/Camera.cpp @@ -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"<reset(); + + osg::ref_ptr projection = _projectionMatrix.get(); + osg::ref_ptr 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->cloneType()); if (!_rendergraphLeft.valid()) _rendergraphLeft = dynamic_cast(_rendergraph->cloneType()); @@ -182,22 +197,57 @@ void SceneView::cull() if (!_rendergraphRight.valid()) _rendergraphRight = dynamic_cast(_rendergraph->cloneType()); if (!_renderStageRight.valid()) _renderStageRight = dynamic_cast(_renderStage->cloneType()); + + // set up the left eye. + osg::ref_ptr 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 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 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 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):