From 54129105a465415da357cf8326a038b04e3cc27b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 28 Jan 2008 15:41:42 +0000 Subject: [PATCH] Added projectorMatrix parameter support to *SphericalDisplay setup functions and .view, this allows one to flip, rotate, or turn up side the position of the projector. Note, projector at base of display is the default. --- include/osgViewer/View | 4 +- src/osgPlugins/osgViewer/View.cpp | 55 +++++++- src/osgViewer/View.cpp | 214 +++++++++++------------------- 3 files changed, 130 insertions(+), 143 deletions(-) diff --git a/include/osgViewer/View b/include/osgViewer/View index 38227ec70..884e751ed 100644 --- a/include/osgViewer/View +++ b/include/osgViewer/View @@ -161,10 +161,10 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter /** Convenience method for spherical display using 6 slave cameras rendering the 6 sides of a cube map, and 7th camera doing distortion correction to present on a spherical display.*/ - void setUpViewFor3DSphericalDisplay(double radius=1.0, double collar=0.45, unsigned int screenNum=0, osg::Image* intensityMap=0); + void setUpViewFor3DSphericalDisplay(double radius=1.0, double collar=0.45, unsigned int screenNum=0, osg::Image* intensityMap=0, const osg::Matrixd& projectorMatrix = osg::Matrixd()); /** Convenience method for spherical display by rendering main scene to as panoramic 2:1 texture and then doing distortion correction to present onto a spherical display.*/ - void setUpViewForPanoramicSphericalDisplay(double radius=1.0, double collar=0.45, unsigned int screenNum=0, osg::Image* intensityMap=0); + void setUpViewForPanoramicSphericalDisplay(double radius=1.0, double collar=0.45, unsigned int screenNum=0, osg::Image* intensityMap=0, const osg::Matrixd& projectorMatrix = osg::Matrixd()); /** Return true if this view contains a specified camera.*/ diff --git a/src/osgPlugins/osgViewer/View.cpp b/src/osgPlugins/osgViewer/View.cpp index efc8dd404..031bcd267 100644 --- a/src/osgPlugins/osgViewer/View.cpp +++ b/src/osgPlugins/osgViewer/View.cpp @@ -21,6 +21,55 @@ osgDB::RegisterDotOsgWrapperProxy View_Proxy View_writeLocalData ); + +static bool readMatrix(osg::Matrix& matrix, osgDB::Input& fr, const char* keyword) +{ + bool iteratorAdvanced = false; + + if (fr[0].matchWord(keyword) && fr[1].isOpenBracket()) + { + int entry = fr[0].getNoNestedBrackets(); + + fr += 2; + + int row=0; + int col=0; + double v; + while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) + { + if (fr[0].getFloat(v)) + { + matrix(row,col)=v; + ++col; + if (col>=4) + { + col = 0; + ++row; + } + ++fr; + } + else fr.advanceOverCurrentFieldOrBlock(); + } + iteratorAdvanced = true; + } + + return iteratorAdvanced; +} + + +static bool writeMatrix(const osg::Matrix& matrix, osgDB::Output& fw, const char* keyword) +{ + fw.indent() << keyword <<" {" << std::endl; + fw.moveIn(); + fw.indent() << matrix(0,0) << " " << matrix(0,1) << " " << matrix(0,2) << " " << matrix(0,3) << std::endl; + fw.indent() << matrix(1,0) << " " << matrix(1,1) << " " << matrix(1,2) << " " << matrix(1,3) << std::endl; + fw.indent() << matrix(2,0) << " " << matrix(2,1) << " " << matrix(2,2) << " " << matrix(2,3) << std::endl; + fw.indent() << matrix(3,0) << " " << matrix(3,1) << " " << matrix(3,2) << " " << matrix(3,3) << std::endl; + fw.moveOut(); + fw.indent() << "}"<< std::endl; + return true; +} + osg::Image* readIntensityImage(osgDB::Input& fr, bool& itrAdvanced) { if (fr.matchSequence("intensityMap {")) @@ -107,6 +156,7 @@ bool View_readLocalData(osg::Object &obj, osgDB::Input &fr) double collar = 0.45; unsigned int screenNum = 0; unsigned int intensityFormat = 8; + osg::Matrix matrix; std::string filename; osg::ref_ptr intensityMap; int entry = fr[0].getNoNestedBrackets(); @@ -122,6 +172,7 @@ bool View_readLocalData(osg::Object &obj, osgDB::Input &fr) if (fr.read("intensityFile",filename)) local_itrAdvanced = true; if (fr.matchSequence("intensityMap {")) intensityMap = readIntensityImage(fr,local_itrAdvanced); if (fr.read("intensityFormat",intensityFormat)) local_itrAdvanced = true; + if (readMatrix(matrix,fr,"projectorMatrix")) local_itrAdvanced = true; if (!local_itrAdvanced) ++fr; } @@ -144,8 +195,8 @@ bool View_readLocalData(osg::Object &obj, osgDB::Input &fr) } - if (matchedFirst) view.setUpViewFor3DSphericalDisplay(radius, collar, screenNum, intensityMap.get()); - else view.setUpViewForPanoramicSphericalDisplay(radius, collar, screenNum, intensityMap.get()); + if (matchedFirst) view.setUpViewFor3DSphericalDisplay(radius, collar, screenNum, intensityMap.get(), matrix); + else view.setUpViewForPanoramicSphericalDisplay(radius, collar, screenNum, intensityMap.get(), matrix); } int x = 0; diff --git a/src/osgViewer/View.cpp b/src/osgViewer/View.cpp index b16013f9a..e68916670 100644 --- a/src/osgViewer/View.cpp +++ b/src/osgViewer/View.cpp @@ -703,7 +703,7 @@ void View::setUpViewOnSingleScreen(unsigned int screenNum) _camera->setReadBuffer(buffer); } -static osg::Geometry* create3DSphericalDisplayDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, double sphere_radius, double collar_radius,osg::Image* intensityMap) +static osg::Geometry* create3DSphericalDisplayDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, double sphere_radius, double collar_radius,osg::Image* intensityMap, const osg::Matrix& projectorMatrix) { osg::Vec3d center(0.0,0.0,0.0); osg::Vec3d eye(0.0,0.0,0.0); @@ -747,8 +747,7 @@ static osg::Geometry* create3DSphericalDisplayDistortionMesh(const osg::Vec3& or osg::Vec3 cursor = bottom; int i,j; - - + if (centerProjection) { for(i=0;ipush_back(cursor); - texcoords0->push_back(texcoord); + texcoords0->push_back(texcoord * projectorMatrix); osg::Vec2 texcoord1(theta/(2.0*osg::PI), 1.0f - phi/osg::PI_2); if (intensityMap) @@ -816,7 +815,7 @@ static osg::Geometry* create3DSphericalDisplayDistortionMesh(const osg::Vec3& or z / sphere_radius); vertices->push_back(cursor); - texcoords0->push_back(texcoord); + texcoords0->push_back(texcoord * projectorMatrix); osg::Vec2 texcoord1(theta/(2.0*osg::PI), 1.0f - phi/osg::PI_2); if (intensityMap) @@ -858,7 +857,7 @@ static osg::Geometry* create3DSphericalDisplayDistortionMesh(const osg::Vec3& or return geometry; } -void View::setUpViewFor3DSphericalDisplay(double radius, double collar, unsigned int screenNum, osg::Image* intensityMap) +void View::setUpViewFor3DSphericalDisplay(double radius, double collar, unsigned int screenNum, osg::Image* intensityMap, const osg::Matrixd& projectorMatrix) { osg::notify(osg::INFO)<<"View::setUpViewFor3DSphericalDisplay(rad="<addDrawable(create3DSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), radius, collar, applyIntensityMapAsColours ? intensityMap : 0)); + geode->addDrawable(create3DSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), radius, collar, applyIntensityMapAsColours ? intensityMap : 0, projectorMatrix)); // new we need to add the texture to the mesh, we do so by creating a // StateSet to contain the Texture StateAttribute. @@ -1063,14 +1061,14 @@ void View::setUpViewFor3DSphericalDisplay(double radius, double collar, unsigned osg::ref_ptr camera = new osg::Camera; camera->setGraphicsContext(gc.get()); camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); - camera->setClearColor( osg::Vec4(0.1,0.1,1.0,1.0) ); + camera->setClearColor( osg::Vec4(0.0,0.0,0.0,1.0) ); camera->setViewport(new osg::Viewport(0, 0, width, height)); GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; camera->setDrawBuffer(buffer); camera->setReadBuffer(buffer); camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); camera->setAllowEventFocus(false); - //camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); + camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); camera->setProjectionMatrixAsOrtho2D(0,width,0,height); @@ -1093,7 +1091,7 @@ void View::setUpViewFor3DSphericalDisplay(double radius, double collar, unsigned } } -static osg::Geometry* createParoramicSphericalDisplayDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, double sphere_radius, double collar_radius, osg::Image* intensityMap) +static osg::Geometry* createParoramicSphericalDisplayDistortionMesh(const osg::Vec3& origin, const osg::Vec3& widthVector, const osg::Vec3& heightVector, double sphere_radius, double collar_radius, osg::Image* intensityMap, const osg::Matrix& projectorMatrix) { osg::Vec3d center(0.0,0.0,0.0); osg::Vec3d eye(0.0,0.0,0.0); @@ -1110,7 +1108,6 @@ static osg::Geometry* createParoramicSphericalDisplayDistortionMesh(const osg::V osg::notify(osg::INFO)<<"createParoramicSphericalDisplayDistortionMesh : Projector position = "<addDrawable(createParoramicSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), radius, collar, applyIntensityMapAsColours ? intensityMap : 0)); + geode->addDrawable(createParoramicSphericalDisplayDistortionMesh(osg::Vec3(0.0f,0.0f,0.0f), osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,height,0.0f), radius, collar, applyIntensityMapAsColours ? intensityMap : 0, projectorMatrix)); // new we need to add the texture to the mesh, we do so by creating a // StateSet to contain the Texture StateAttribute. @@ -1406,14 +1342,14 @@ void View::setUpViewForPanoramicSphericalDisplay(double radius, double collar, u osg::ref_ptr camera = new osg::Camera; camera->setGraphicsContext(gc.get()); camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT ); - camera->setClearColor( osg::Vec4(0.1,0.1,1.0,1.0) ); + camera->setClearColor( osg::Vec4(0.0,0.0,0.0,1.0) ); camera->setViewport(new osg::Viewport(0, 0, width, height)); GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; camera->setDrawBuffer(buffer); camera->setReadBuffer(buffer); camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); camera->setAllowEventFocus(false); - //camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); + camera->setInheritanceMask(camera->getInheritanceMask() & ~osg::CullSettings::CLEAR_COLOR & ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE); //camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); camera->setProjectionMatrixAsOrtho2D(0,width,0,height);