Introduced new DisplaySettings::set/getDisplayType() and environemtal variables
to and command line arguments to set it. Added support for using the DisplaySettings::getDisplayType() to detect use of a Head Mounted Display when doing stereo so that the asymtric frustum can be switched off.
This commit is contained in:
@@ -45,6 +45,7 @@ DisplaySettings::~DisplaySettings()
|
||||
|
||||
void DisplaySettings::copy(const DisplaySettings& vs)
|
||||
{
|
||||
_displayType = vs._displayType;
|
||||
_stereoMode = vs._stereoMode;
|
||||
_eyeSeparation = vs._eyeSeparation;
|
||||
_screenDistance = vs._screenDistance;
|
||||
@@ -83,6 +84,8 @@ void DisplaySettings::merge(const DisplaySettings& vs)
|
||||
|
||||
void DisplaySettings::setDefaults()
|
||||
{
|
||||
_displayType = MONITOR;
|
||||
|
||||
_stereo = false;
|
||||
_stereoMode = ANAGLYPHIC;
|
||||
_eyeSeparation = 0.05f;
|
||||
@@ -106,21 +109,46 @@ void DisplaySettings::setDefaults()
|
||||
_maxNumOfGraphicsContexts = 3;
|
||||
}
|
||||
|
||||
static ApplicationUsageProxy DisplaySetting_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO_MODE <mode>","QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE");
|
||||
static ApplicationUsageProxy DisplaySetting_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO <mode>","OFF | ON");
|
||||
static ApplicationUsageProxy DisplaySetting_e2(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EYE_SEPARATION <float>","physical distance between eyes");
|
||||
static ApplicationUsageProxy DisplaySetting_e3(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_DISTANCE <float>","physical distance between eyes and screen");
|
||||
static ApplicationUsageProxy DisplaySetting_e4(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_HEIGHT <float>","physical screen height");
|
||||
static ApplicationUsageProxy DisplaySetting_e5(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING <mode>","LEFT_EYE_LEFT_VIEWPORT | LEFT_EYE_RIGHT_VIEWPORT");
|
||||
static ApplicationUsageProxy DisplaySetting_e8(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION <float>","number of pixels between viewports");
|
||||
static ApplicationUsageProxy DisplaySetting_e9(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING <mode>","LEFT_EYE_TOP_VIEWPORT | LEFT_EYE_BOTTOM_VIEWPORT");
|
||||
static ApplicationUsageProxy DisplaySetting_e10(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO <mode>","OFF | ON Default to ON to compenstate for the compression of the aspect ratio when viewing in split screen stereo. Note, if you are setting fovx and fovy explicityly OFF should be used.");
|
||||
static ApplicationUsageProxy DisplaySetting_e11(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_SEPARATION <float>","number of pixels between viewports");
|
||||
static ApplicationUsageProxy DisplaySetting_e12(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS <int>","maximum number of graphics contexts to be used with applications.");
|
||||
static ApplicationUsageProxy DisplaySetting_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_DISPLAY_TYPE <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
|
||||
static ApplicationUsageProxy DisplaySetting_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO_MODE <mode>","QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE");
|
||||
static ApplicationUsageProxy DisplaySetting_e2(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO <mode>","OFF | ON");
|
||||
static ApplicationUsageProxy DisplaySetting_e3(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EYE_SEPARATION <float>","physical distance between eyes");
|
||||
static ApplicationUsageProxy DisplaySetting_e4(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_DISTANCE <float>","physical distance between eyes and screen");
|
||||
static ApplicationUsageProxy DisplaySetting_e5(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_HEIGHT <float>","physical screen height");
|
||||
static ApplicationUsageProxy DisplaySetting_e6(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING <mode>","LEFT_EYE_LEFT_VIEWPORT | LEFT_EYE_RIGHT_VIEWPORT");
|
||||
static ApplicationUsageProxy DisplaySetting_e7(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION <float>","number of pixels between viewports");
|
||||
static ApplicationUsageProxy DisplaySetting_e8(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING <mode>","LEFT_EYE_TOP_VIEWPORT | LEFT_EYE_BOTTOM_VIEWPORT");
|
||||
static ApplicationUsageProxy DisplaySetting_e9(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO <mode>","OFF | ON Default to ON to compenstate for the compression of the aspect ratio when viewing in split screen stereo. Note, if you are setting fovx and fovy explicityly OFF should be used.");
|
||||
static ApplicationUsageProxy DisplaySetting_e10(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_SEPARATION <float>","number of pixels between viewports");
|
||||
static ApplicationUsageProxy DisplaySetting_e11(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS <int>","maximum number of graphics contexts to be used with applications.");
|
||||
|
||||
void DisplaySettings::readEnvironmentalVariables()
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
if ((ptr = getenv("OSG_DISPLAY_TYPE")) != 0)
|
||||
{
|
||||
if (strcmp(ptr,"MONITOR")==0)
|
||||
{
|
||||
_displayType = MONITOR;
|
||||
}
|
||||
else
|
||||
if (strcmp(ptr,"POWERWALL")==0)
|
||||
{
|
||||
_displayType = POWERWALL;
|
||||
}
|
||||
else
|
||||
if (strcmp(ptr,"REALITY_CENTER")==0)
|
||||
{
|
||||
_displayType = REALITY_CENTER;
|
||||
}
|
||||
else
|
||||
if (strcmp(ptr,"HEAD_MOUNTED_DISPLAY")==0)
|
||||
{
|
||||
_displayType = HEAD_MOUNTED_DISPLAY;
|
||||
}
|
||||
}
|
||||
|
||||
if( (ptr = getenv("OSG_STEREO_MODE")) != 0)
|
||||
{
|
||||
if (strcmp(ptr,"QUAD_BUFFER")==0)
|
||||
@@ -244,12 +272,21 @@ void DisplaySettings::readCommandLine(ArgumentParser& arguments)
|
||||
// report the usage options.
|
||||
if (arguments.getApplicationUsage())
|
||||
{
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--display <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--stereo","Use default stereo mode which is ANAGLYPHIC if not overriden by environmental variable");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--stereo <mode>","ANAGLYPHIC | QUAD_BUFFER | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE | ON | OFF ");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--rgba","Request a RGBA color buffer visual");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--stencil","Request a stencil buffer visual");
|
||||
}
|
||||
|
||||
std::string str;
|
||||
while(arguments.read("--display",str))
|
||||
{
|
||||
if (str=="MONITOR") _displayType = MONITOR;
|
||||
else if (str=="POWERWALL") _displayType = POWERWALL;
|
||||
else if (str=="REALITY_CENTER") _displayType = REALITY_CENTER;
|
||||
else if (str=="HEAD_MOUNTED_DISPLAY") _displayType = HEAD_MOUNTED_DISPLAY;
|
||||
}
|
||||
|
||||
int pos;
|
||||
while ((pos=arguments.find("--stereo"))!=0)
|
||||
|
||||
@@ -67,15 +67,8 @@ SceneView::~SceneView()
|
||||
|
||||
void SceneView::setDefaults()
|
||||
{
|
||||
if (!_projectionMatrix)
|
||||
{
|
||||
_projectionMatrix = new RefMatrix();
|
||||
_projectionMatrix->makePerspective(50.0f,1.4f,1.0f,10000.0f);
|
||||
}
|
||||
if (!_viewMatrix)
|
||||
{
|
||||
_viewMatrix = new RefMatrix();
|
||||
}
|
||||
_projectionMatrix.makePerspective(50.0f,1.4f,1.0f,10000.0f);
|
||||
_viewMatrix.makeIdentity();
|
||||
|
||||
_globalStateSet = new osg::StateSet;
|
||||
|
||||
@@ -193,6 +186,158 @@ void SceneView::update()
|
||||
|
||||
}
|
||||
|
||||
osg::Matrixd SceneView::computeLeftEyeProjectionImplementation(const osg::Matrixd& projection) const
|
||||
{
|
||||
double fusionDistance = _displaySettings->getScreenDistance();
|
||||
switch(_fusionDistanceMode)
|
||||
{
|
||||
case(USE_FUSION_DISTANCE_VALUE):
|
||||
fusionDistance = _fusionDistanceValue;
|
||||
break;
|
||||
case(PROPORTIONAL_TO_SCREEN_DISTANCE):
|
||||
fusionDistance *= _fusionDistanceValue;
|
||||
break;
|
||||
}
|
||||
|
||||
double iod = _displaySettings->getEyeSeparation();
|
||||
double sd = _displaySettings->getScreenDistance();
|
||||
double scale_x = 1.0;
|
||||
double scale_y = 1.0;
|
||||
|
||||
if (_displaySettings->getSplitStereoAutoAjustAspectRatio())
|
||||
{
|
||||
switch(_displaySettings->getStereoMode())
|
||||
{
|
||||
case(osg::DisplaySettings::HORIZONTAL_SPLIT):
|
||||
scale_x = 2.0;
|
||||
break;
|
||||
case(osg::DisplaySettings::VERTICAL_SPLIT):
|
||||
scale_y = 2.0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_displaySettings->getDisplayType()==osg::DisplaySettings::HEAD_MOUNTED_DISPLAY)
|
||||
{
|
||||
// head mounted display has the same projection matrix for left and right eyes.
|
||||
return osg::Matrixd::scale(scale_x,scale_y,1.0) *
|
||||
projection;
|
||||
}
|
||||
else
|
||||
{
|
||||
// all other display types assume working like a projected power wall
|
||||
// need to shjear projection matrix to account for asymetric frustum due to eye offset.
|
||||
return osg::Matrixd(1.0,0.0,0.0,0.0,
|
||||
0.0,1.0,0.0,0.0,
|
||||
iod/(2.0*sd),0.0,1.0,0.0,
|
||||
0.0,0.0,0.0,1.0) *
|
||||
osg::Matrixd::scale(scale_x,scale_y,1.0) *
|
||||
projection;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Matrixd SceneView::computeLeftEyeViewImplementation(const osg::Matrixd& view) const
|
||||
{
|
||||
double fusionDistance = _displaySettings->getScreenDistance();
|
||||
switch(_fusionDistanceMode)
|
||||
{
|
||||
case(USE_FUSION_DISTANCE_VALUE):
|
||||
fusionDistance = _fusionDistanceValue;
|
||||
break;
|
||||
case(PROPORTIONAL_TO_SCREEN_DISTANCE):
|
||||
fusionDistance *= _fusionDistanceValue;
|
||||
break;
|
||||
}
|
||||
|
||||
double iod = _displaySettings->getEyeSeparation();
|
||||
double sd = _displaySettings->getScreenDistance();
|
||||
double es = 0.5f*iod*(fusionDistance/sd);
|
||||
|
||||
return view *
|
||||
osg::Matrixd(1.0,0.0,0.0,0.0,
|
||||
0.0,1.0,0.0,0.0,
|
||||
0.0,0.0,1.0,0.0,
|
||||
es,0.0,0.0,1.0);
|
||||
}
|
||||
|
||||
osg::Matrixd SceneView::computeRightEyeProjectionImplementation(const osg::Matrixd& projection) const
|
||||
{
|
||||
double fusionDistance = _displaySettings->getScreenDistance();
|
||||
switch(_fusionDistanceMode)
|
||||
{
|
||||
case(USE_FUSION_DISTANCE_VALUE):
|
||||
fusionDistance = _fusionDistanceValue;
|
||||
break;
|
||||
case(PROPORTIONAL_TO_SCREEN_DISTANCE):
|
||||
fusionDistance *= _fusionDistanceValue;
|
||||
break;
|
||||
}
|
||||
|
||||
double iod = _displaySettings->getEyeSeparation();
|
||||
double sd = _displaySettings->getScreenDistance();
|
||||
double scale_x = 1.0;
|
||||
double scale_y = 1.0;
|
||||
|
||||
if (_displaySettings->getSplitStereoAutoAjustAspectRatio())
|
||||
{
|
||||
switch(_displaySettings->getStereoMode())
|
||||
{
|
||||
case(osg::DisplaySettings::HORIZONTAL_SPLIT):
|
||||
scale_x = 2.0;
|
||||
break;
|
||||
case(osg::DisplaySettings::VERTICAL_SPLIT):
|
||||
scale_y = 2.0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_displaySettings->getDisplayType()==osg::DisplaySettings::HEAD_MOUNTED_DISPLAY)
|
||||
{
|
||||
// head mounted display has the same projection matrix for left and right eyes.
|
||||
return osg::Matrixd::scale(scale_x,scale_y,1.0) *
|
||||
projection;
|
||||
}
|
||||
else
|
||||
{
|
||||
// all other display types assume working like a projected power wall
|
||||
// need to shjear projection matrix to account for asymetric frustum due to eye offset.
|
||||
return osg::Matrixd(1.0,0.0,0.0,0.0,
|
||||
0.0,1.0,0.0,0.0,
|
||||
-iod/(2.0*sd),0.0,1.0,0.0,
|
||||
0.0,0.0,0.0,1.0) *
|
||||
osg::Matrixd::scale(scale_x,scale_y,1.0) *
|
||||
projection;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Matrixd SceneView::computeRightEyeViewImplementation(const osg::Matrixd& view) const
|
||||
{
|
||||
float fusionDistance = _displaySettings->getScreenDistance();
|
||||
switch(_fusionDistanceMode)
|
||||
{
|
||||
case(USE_FUSION_DISTANCE_VALUE):
|
||||
fusionDistance = _fusionDistanceValue;
|
||||
break;
|
||||
case(PROPORTIONAL_TO_SCREEN_DISTANCE):
|
||||
fusionDistance *= _fusionDistanceValue;
|
||||
break;
|
||||
}
|
||||
|
||||
double iod = _displaySettings->getEyeSeparation();
|
||||
double sd = _displaySettings->getScreenDistance();
|
||||
double es = 0.5*iod*(fusionDistance/sd);
|
||||
|
||||
return view *
|
||||
osg::Matrixd(1.0,0.0,0.0,0.0,
|
||||
0.0,1.0,0.0,0.0,
|
||||
0.0,0.0,1.0,0.0,
|
||||
-es,0.0,0.0,1.0);
|
||||
}
|
||||
|
||||
void SceneView::cull()
|
||||
{
|
||||
|
||||
@@ -217,12 +362,6 @@ void SceneView::cull()
|
||||
_state->setDisplaySettings(_displaySettings.get());
|
||||
|
||||
|
||||
osg::ref_ptr<osg::RefMatrix> projection = _projectionMatrix.get();
|
||||
osg::ref_ptr<osg::RefMatrix> modelview = _viewMatrix.get();
|
||||
|
||||
if (!projection) projection = new osg::RefMatrix();
|
||||
if (!modelview) modelview = new osg::RefMatrix();
|
||||
|
||||
if (!_cullVisitor)
|
||||
{
|
||||
osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView:: attached, creating a default CullVisitor automatically."<< std::endl;
|
||||
@@ -242,60 +381,18 @@ void SceneView::cull()
|
||||
if (_displaySettings.valid() && _displaySettings->getStereo())
|
||||
{
|
||||
|
||||
float fusionDistance = _displaySettings->getScreenDistance();
|
||||
switch(_fusionDistanceMode)
|
||||
{
|
||||
case(USE_FUSION_DISTANCE_VALUE):
|
||||
fusionDistance = _fusionDistanceValue;
|
||||
break;
|
||||
case(PROPORTIONAL_TO_SCREEN_DISTANCE):
|
||||
fusionDistance *= _fusionDistanceValue;
|
||||
break;
|
||||
}
|
||||
|
||||
float iod = _displaySettings->getEyeSeparation();
|
||||
float sd = _displaySettings->getScreenDistance();
|
||||
float es = 0.5f*iod*(fusionDistance/sd);
|
||||
|
||||
if (_displaySettings->getStereoMode()==osg::DisplaySettings::LEFT_EYE)
|
||||
{
|
||||
// set up the left eye.
|
||||
osg::ref_ptr<osg::RefMatrix> projectionLeft = new osg::RefMatrix(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::RefMatrix> modelviewLeft = new osg::RefMatrix( (*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());
|
||||
cullStage(computeLeftEyeProjection(_projectionMatrix),computeLeftEyeView(_viewMatrix),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
|
||||
|
||||
}
|
||||
else if (_displaySettings->getStereoMode()==osg::DisplaySettings::RIGHT_EYE)
|
||||
{
|
||||
// set up the right eye.
|
||||
osg::ref_ptr<osg::RefMatrix> projectionRight = new osg::RefMatrix(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::RefMatrix> modelviewRight = new osg::RefMatrix( (*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());
|
||||
|
||||
|
||||
cullStage(computeRightEyeProjection(_projectionMatrix),computeRightEyeView(_viewMatrix),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -309,65 +406,13 @@ void SceneView::cull()
|
||||
if (!_renderStageRight.valid()) _renderStageRight = dynamic_cast<RenderStage*>(_renderStage->clone(osg::CopyOp::DEEP_COPY_ALL));
|
||||
|
||||
|
||||
|
||||
|
||||
osg::Matrix projection_scale;
|
||||
|
||||
|
||||
if (_displaySettings->getSplitStereoAutoAjustAspectRatio())
|
||||
{
|
||||
|
||||
switch(_displaySettings->getStereoMode())
|
||||
{
|
||||
case(osg::DisplaySettings::HORIZONTAL_SPLIT):
|
||||
projection_scale.makeScale(2.0f,1.0f,1.0f);
|
||||
break;
|
||||
case(osg::DisplaySettings::VERTICAL_SPLIT):
|
||||
projection_scale.makeScale(1.0f,2.0f,1.0f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// set up the left eye.
|
||||
osg::ref_ptr<osg::RefMatrix> projectionLeft = new osg::RefMatrix(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_scale*
|
||||
(*projection));
|
||||
|
||||
|
||||
|
||||
osg::ref_ptr<osg::RefMatrix> modelviewLeft = new osg::RefMatrix( (*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());
|
||||
cullStage(computeLeftEyeProjection(_projectionMatrix),computeLeftEyeView(_viewMatrix),_cullVisitorLeft.get(),_rendergraphLeft.get(),_renderStageLeft.get());
|
||||
|
||||
|
||||
// set up the right eye.
|
||||
osg::ref_ptr<osg::RefMatrix> projectionRight = new osg::RefMatrix(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_scale*
|
||||
(*projection));
|
||||
|
||||
osg::ref_ptr<osg::RefMatrix> modelviewRight = new osg::RefMatrix( (*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());
|
||||
cullStage(computeRightEyeProjection(_projectionMatrix),computeRightEyeView(_viewMatrix),_cullVisitorRight.get(),_rendergraphRight.get(),_renderStageRight.get());
|
||||
|
||||
}
|
||||
|
||||
@@ -376,14 +421,14 @@ void SceneView::cull()
|
||||
{
|
||||
|
||||
_cullVisitor->setTraversalMask(_cullMask);
|
||||
cullStage(projection.get(),modelview.get(),_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
|
||||
cullStage(_projectionMatrix,_viewMatrix,_cullVisitor.get(),_rendergraph.get(),_renderStage.get());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SceneView::cullStage(osg::RefMatrix* projection,osg::RefMatrix* modelview,osgUtil::CullVisitor* cullVisitor, osgUtil::RenderGraph* rendergraph, osgUtil::RenderStage* renderStage)
|
||||
void SceneView::cullStage(const osg::Matrixd& projection,const osg::Matrixd& modelview,osgUtil::CullVisitor* cullVisitor, osgUtil::RenderGraph* rendergraph, osgUtil::RenderStage* renderStage)
|
||||
{
|
||||
|
||||
if (!_sceneData || !_viewport->valid()) return;
|
||||
@@ -391,6 +436,8 @@ void SceneView::cullStage(osg::RefMatrix* projection,osg::RefMatrix* modelview,o
|
||||
if (!_initCalled) init();
|
||||
|
||||
|
||||
osg::ref_ptr<RefMatrix> proj = new osg::RefMatrix(projection);
|
||||
osg::ref_ptr<RefMatrix> mv = new osg::RefMatrix(modelview);
|
||||
|
||||
// collect any occluder in the view frustum.
|
||||
if (_sceneData->containsOccluderNodes())
|
||||
@@ -408,8 +455,8 @@ void SceneView::cullStage(osg::RefMatrix* projection,osg::RefMatrix* modelview,o
|
||||
}
|
||||
|
||||
cov.pushViewport(_viewport.get());
|
||||
cov.pushProjectionMatrix(projection);
|
||||
cov.pushModelViewMatrix(modelview);
|
||||
cov.pushProjectionMatrix(proj.get());
|
||||
cov.pushModelViewMatrix(mv.get());
|
||||
|
||||
// traverse the scene graph to search for occluder in there new positions.
|
||||
_sceneData->accept(cov);
|
||||
@@ -473,7 +520,7 @@ void SceneView::cullStage(osg::RefMatrix* projection,osg::RefMatrix* modelview,o
|
||||
else osg::notify(osg::WARN)<<"Warning: no osg::Light attached to ogUtil::SceneView to provide head light.*/"<<std::endl;
|
||||
break;
|
||||
case(SKY_LIGHT):
|
||||
if (_light.valid()) renderStage->addPositionedAttribute(modelview,_light.get());
|
||||
if (_light.valid()) renderStage->addPositionedAttribute(mv.get(),_light.get());
|
||||
else osg::notify(osg::WARN)<<"Warning: no osg::Light attached to ogUtil::SceneView to provide sky light.*/"<<std::endl;
|
||||
break;
|
||||
case(NO_SCENEVIEW_LIGHT):
|
||||
@@ -485,8 +532,8 @@ void SceneView::cullStage(osg::RefMatrix* projection,osg::RefMatrix* modelview,o
|
||||
|
||||
|
||||
cullVisitor->pushViewport(_viewport.get());
|
||||
cullVisitor->pushProjectionMatrix(projection);
|
||||
cullVisitor->pushModelViewMatrix(modelview);
|
||||
cullVisitor->pushProjectionMatrix(proj.get());
|
||||
cullVisitor->pushModelViewMatrix(mv.get());
|
||||
|
||||
|
||||
// traverse the scene graph to generate the rendergraph.
|
||||
@@ -553,7 +600,7 @@ void SceneView::draw()
|
||||
//osg::Timer_t tend = timer.tick();
|
||||
//std::cout<<"time to flush rendering objects"<<timer.delta_m(tstart,tend)<<std::endl;
|
||||
|
||||
if (_viewMatrix.valid()) _state->setInitialViewMatrix(_viewMatrix.get());
|
||||
_state->setInitialViewMatrix(new osg::RefMatrix(_viewMatrix));
|
||||
|
||||
RenderLeaf* previous = NULL;
|
||||
if (_displaySettings.valid() && _displaySettings->getStereo())
|
||||
@@ -862,13 +909,7 @@ bool SceneView::projectObjectIntoWindow(const osg::Vec3& object,osg::Vec3& windo
|
||||
|
||||
const osg::Matrix SceneView::computeMVPW() const
|
||||
{
|
||||
osg::Matrix matrix;
|
||||
|
||||
if (_viewMatrix.valid())
|
||||
matrix = (*_viewMatrix);
|
||||
|
||||
if (_projectionMatrix.valid())
|
||||
matrix.postMult(*_projectionMatrix);
|
||||
osg::Matrix matrix( _viewMatrix * _projectionMatrix);
|
||||
|
||||
if (_viewport.valid())
|
||||
matrix.postMult(_viewport->computeWindowMatrix());
|
||||
@@ -893,18 +934,11 @@ void SceneView::clearArea(int x,int y,int width,int height,const osg::Vec4& colo
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
}
|
||||
|
||||
void SceneView::setProjectionMatrix(const osg::Matrix& matrix)
|
||||
{
|
||||
if (!_projectionMatrix) _projectionMatrix = new osg::RefMatrix(matrix);
|
||||
else _projectionMatrix->set(matrix);
|
||||
}
|
||||
|
||||
|
||||
void SceneView::setProjectionMatrixAsOrtho(double left, double right,
|
||||
double bottom, double top,
|
||||
double zNear, double zFar)
|
||||
{
|
||||
setProjectionMatrix(osg::Matrix::ortho(left, right,
|
||||
setProjectionMatrix(osg::Matrixd::ortho(left, right,
|
||||
bottom, top,
|
||||
zNear, zFar));
|
||||
}
|
||||
@@ -912,7 +946,7 @@ void SceneView::setProjectionMatrixAsOrtho(double left, double right,
|
||||
void SceneView::setProjectionMatrixAsOrtho2D(double left, double right,
|
||||
double bottom, double top)
|
||||
{
|
||||
setProjectionMatrix(osg::Matrix::ortho2D(left, right,
|
||||
setProjectionMatrix(osg::Matrixd::ortho2D(left, right,
|
||||
bottom, top));
|
||||
}
|
||||
|
||||
@@ -920,7 +954,7 @@ void SceneView::setProjectionMatrixAsFrustum(double left, double right,
|
||||
double bottom, double top,
|
||||
double zNear, double zFar)
|
||||
{
|
||||
setProjectionMatrix(osg::Matrix::frustum(left, right,
|
||||
setProjectionMatrix(osg::Matrixd::frustum(left, right,
|
||||
bottom, top,
|
||||
zNear, zFar));
|
||||
}
|
||||
@@ -928,7 +962,7 @@ void SceneView::setProjectionMatrixAsFrustum(double left, double right,
|
||||
void SceneView::setProjectionMatrixAsPerspective(double fovy,double aspectRatio,
|
||||
double zNear, double zFar)
|
||||
{
|
||||
setProjectionMatrix(osg::Matrix::perspective(fovy,aspectRatio,
|
||||
setProjectionMatrix(osg::Matrixd::perspective(fovy,aspectRatio,
|
||||
zNear, zFar));
|
||||
}
|
||||
|
||||
@@ -936,53 +970,32 @@ bool SceneView::getProjectionMatrixAsOrtho(double& left, double& right,
|
||||
double& bottom, double& top,
|
||||
double& zNear, double& zFar)
|
||||
{
|
||||
if (_projectionMatrix.valid())
|
||||
{
|
||||
return _projectionMatrix->getOrtho(left, right,
|
||||
bottom, top,
|
||||
zNear, zFar);
|
||||
}
|
||||
return false;
|
||||
return _projectionMatrix.getOrtho(left, right,
|
||||
bottom, top,
|
||||
zNear, zFar);
|
||||
}
|
||||
|
||||
bool SceneView::getProjectionMatrixAsFrustum(double& left, double& right,
|
||||
double& bottom, double& top,
|
||||
double& zNear, double& zFar)
|
||||
{
|
||||
if (_projectionMatrix.valid())
|
||||
{
|
||||
return _projectionMatrix->getFrustum(left, right,
|
||||
bottom, top,
|
||||
zNear, zFar);
|
||||
}
|
||||
return false;
|
||||
return _projectionMatrix.getFrustum(left, right,
|
||||
bottom, top,
|
||||
zNear, zFar);
|
||||
}
|
||||
|
||||
bool SceneView::getProjectionMatrixAsPerspective(double& fovy,double& aspectRatio,
|
||||
double& zNear, double& zFar)
|
||||
{
|
||||
if (_projectionMatrix.valid())
|
||||
{
|
||||
return _projectionMatrix->getPerspective(fovy, aspectRatio, zNear, zFar);
|
||||
}
|
||||
return false;
|
||||
return _projectionMatrix.getPerspective(fovy, aspectRatio, zNear, zFar);
|
||||
}
|
||||
|
||||
void SceneView::setViewMatrix(const osg::Matrix& matrix)
|
||||
{
|
||||
if (!_viewMatrix) _viewMatrix = new osg::RefMatrix(matrix);
|
||||
else _viewMatrix->set(matrix);
|
||||
}
|
||||
|
||||
void SceneView::setViewMatrixAsLookAt(const Vec3& eye,const Vec3& center,const Vec3& up)
|
||||
{
|
||||
setViewMatrix(osg::Matrix::lookAt(eye,center,up));
|
||||
setViewMatrix(osg::Matrixd::lookAt(eye,center,up));
|
||||
}
|
||||
|
||||
void SceneView::getViewMatrixAsLookAt(Vec3& eye,Vec3& center,Vec3& up,float lookDistance)
|
||||
{
|
||||
if (_viewMatrix.valid())
|
||||
{
|
||||
_viewMatrix->getLookAt(eye,center,up,lookDistance);
|
||||
}
|
||||
_viewMatrix.getLookAt(eye,center,up,lookDistance);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user