Hi Robert, hope you enjoyed your holiday. Attached is the fix for ReaderWriterCFG to load offset for camera into view matrix if only single camera is defined in the config file.
The cameras from .cfg files were loaded as slaves initially. There was a change in 2014 to reuse the View::getCamera() instead of creating a slave for single camera but that change removed loading offset onto camera's view matrix. The 2014 change affected only single camera mode, the multiple cameras config still loads offsets onto view matrices. The 2014 resulted in single cam offset being ignored and unavailable from outside the config reader. My change copies the multiple camera behaviour for single camera and brings back pre 2014 functionality while still reusing master camera. With this change one can still use same camera configuration (projection, offsets) in both single and mulitple cam setups. Best regards, Marcin Prus
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2007 Cedric Pinson * * This application is open source and may be redistributed and/or modified * freely and without restriction, both in commercial and non commercial * applications, as long as this copyright notice is maintained. * * This application is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Authors: * Cedric Pinson <[email protected]> * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifndef DATADIR #define DATADIR "." #endif // DATADIR #include <osg/GraphicsContext> #include "RenderSurface.h" #include "CameraConfig.h" #include <osgDB/FileNameUtils> #include <osgDB/FileUtils> #include <osgDB/Registry> #include <osgDB/Input> #include <osgDB/Output> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osg/io_utils> using namespace osgProducer; static osg::GraphicsContext::Traits* buildTrait(RenderSurface& rs) { VisualChooser& vc = *rs.getVisualChooser(); osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits; for (std::vector<VisualChooser::VisualAttribute>::iterator it = vc._visual_attributes.begin(); it != vc._visual_attributes.end(); it++) { switch(it->_attribute) { case(VisualChooser::UseGL): break; // on by default in osgViewer case(VisualChooser::BufferSize): break; // no present mapping case(VisualChooser::Level): traits->level = it->_parameter; break; case(VisualChooser::RGBA): break; // automatically set in osgViewer case(VisualChooser::DoubleBuffer): traits->doubleBuffer = true; break; case(VisualChooser::Stereo): traits->quadBufferStereo = true; break; case(VisualChooser::AuxBuffers): break; // no present mapping case(VisualChooser::RedSize): traits->red = it->_parameter; break; case(VisualChooser::GreenSize): traits->green = it->_parameter; break; case(VisualChooser::BlueSize): traits->blue = it->_parameter; break; case(VisualChooser::AlphaSize): traits->alpha = it->_parameter; break; case(VisualChooser::DepthSize): traits->depth = it->_parameter; break; case(VisualChooser::StencilSize): traits->stencil = it->_parameter; break; case(VisualChooser::AccumRedSize): break; // no present mapping case(VisualChooser::AccumGreenSize): break; // no present mapping case(VisualChooser::AccumBlueSize): break; // no present mapping case(VisualChooser::AccumAlphaSize): break; // no present mapping case(VisualChooser::Samples): traits->samples = it->_parameter; break; case(VisualChooser::SampleBuffers): traits->sampleBuffers = 1; break; } } OSG_INFO<<"ReaderWriterCFG buildTrait traits->depth="<<traits->depth<<std::endl; OSG_INFO<<"ReaderWriterCFG buildTrait traits->samples="<<traits->samples<<std::endl; OSG_INFO<<"ReaderWriterCFG buildTrait traits->sampleBuffers="<<traits->sampleBuffers<<std::endl; traits->hostName = rs.getHostName(); traits->displayNum = rs.getDisplayNum(); traits->screenNum = rs.getScreenNum(); traits->windowName = rs.getWindowName(); traits->x = rs.getWindowOriginX(); traits->y = rs.getWindowOriginY(); traits->width = rs.getWindowWidth(); traits->height = rs.getWindowHeight(); traits->windowDecoration = rs.usesBorder(); traits->sharedContext = 0; traits->pbuffer = (rs.getDrawableType()==osgProducer::RenderSurface::DrawableType_PBuffer); traits->overrideRedirect = rs.usesOverrideRedirect(); return traits; } static osgViewer::View* load(const std::string& file, const osgDB::ReaderWriter::Options* /*option*/) { osg::ref_ptr<CameraConfig> config = new CameraConfig; //std::cout << "Parse file " << file << std::endl; config->parseFile(file); RenderSurface* rs = 0; Camera* cm = 0; std::map<RenderSurface*,osg::ref_ptr<osg::GraphicsContext> > surfaces; osg::ref_ptr<osgViewer::View> _view = new osgViewer::View; if (config->getNumberOfCameras()==1) { cm = config->getCamera(0); rs = cm->getRenderSurface(); if (rs->getDrawableType() != osgProducer::RenderSurface::DrawableType_Window) return 0; osg::ref_ptr<const osg::GraphicsContext::Traits> traits; osg::ref_ptr<osg::GraphicsContext> gc; if (surfaces.find(rs) != surfaces.end()) { gc = surfaces[rs]; traits = gc.valid() ? gc->getTraits() : 0; } else { osg::GraphicsContext::Traits* newtraits = buildTrait(*rs); #if 0 osg::GraphicsContext::ScreenIdentifier si; si.readDISPLAY(); if (si.displayNum>=0) newtraits->displayNum = si.displayNum; if (si.screenNum>=0) newtraits->screenNum = si.screenNum; #endif gc = osg::GraphicsContext::createGraphicsContext(newtraits); surfaces[rs] = gc.get(); traits = gc.valid() ? gc->getTraits() : 0; } // std::cout << rs->getWindowName() << " " << rs->getWindowOriginX() << " " << rs->getWindowOriginY() << " " << rs->getWindowWidth() << " " << rs->getWindowHeight() << std::endl; if (gc.valid()) { OSG_INFO<<" GraphicsWindow has been created successfully."<<std::endl; osg::ref_ptr<osg::Camera> camera = _view->getCamera(); camera->setGraphicsContext(gc.get()); int x,y; unsigned int width,height; cm->applyLens(); cm->getProjectionRectangle(x, y, width, height); camera->setViewport(new osg::Viewport(x, y, width, height)); GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; camera->setDrawBuffer(buffer); camera->setReadBuffer(buffer); camera->setProjectionMatrix(osg::Matrixd(cm->getProjectionMatrix())); osg::Matrix offset = osg::Matrix::identity(); cm->setViewByMatrix(offset); camera->setViewMatrix(osg::Matrixd(cm->getPositionAndAttitudeMatrix())); #if 0 std::cout << "Matrix Projection " << projection << std::endl; std::cout << "Matrix Projection master " << _view->getCamera()->getProjectionMatrix() << std::endl; // will work only if it's a post multyply in the producer camera std::cout << "Matrix View " << view << std::endl; std::cout << _view->getCamera()->getProjectionMatrix() * offsetProjection << std::endl; #endif } else { OSG_INFO<<" GraphicsWindow has not been created successfully."<<std::endl; return 0; } } else { for (int i = 0; i < (int)config->getNumberOfCameras(); i++) { cm = config->getCamera(i); rs = cm->getRenderSurface(); if (rs->getDrawableType() != osgProducer::RenderSurface::DrawableType_Window) continue; osg::ref_ptr<const osg::GraphicsContext::Traits> traits; osg::ref_ptr<osg::GraphicsContext> gc; if (surfaces.find(rs) != surfaces.end()) { gc = surfaces[rs]; traits = gc.valid() ? gc->getTraits() : 0; } else { osg::GraphicsContext::Traits* newtraits = buildTrait(*rs); #if 0 osg::GraphicsContext::ScreenIdentifier si; si.readDISPLAY(); if (si.displayNum>=0) newtraits->displayNum = si.displayNum; if (si.screenNum>=0) newtraits->screenNum = si.screenNum; #endif gc = osg::GraphicsContext::createGraphicsContext(newtraits); surfaces[rs] = gc.get(); traits = gc.valid() ? gc->getTraits() : 0; } // std::cout << rs->getWindowName() << " " << rs->getWindowOriginX() << " " << rs->getWindowOriginY() << " " << rs->getWindowWidth() << " " << rs->getWindowHeight() << std::endl; if (gc.valid()) { OSG_INFO<<" GraphicsWindow has been created successfully."<<std::endl; osg::ref_ptr<osg::Camera> camera = new osg::Camera; camera->setGraphicsContext(gc.get()); int x,y; unsigned int width,height; cm->applyLens(); cm->getProjectionRectangle(x, y, width, height); camera->setViewport(new osg::Viewport(x, y, width, height)); GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; camera->setDrawBuffer(buffer); camera->setReadBuffer(buffer); osg::Matrix projection(cm->getProjectionMatrix()); osg::Matrix offset = osg::Matrix::identity(); cm->setViewByMatrix(offset); osg::Matrix view = osg::Matrix(cm->getPositionAndAttitudeMatrix()); // setup projection from parent osg::Matrix offsetProjection = osg::Matrix::inverse(_view->getCamera()->getProjectionMatrix()) * projection; _view->addSlave(camera.get(), offsetProjection, view); #if 0 std::cout << "Matrix Projection " << projection << std::endl; std::cout << "Matrix Projection master " << _view->getCamera()->getProjectionMatrix() << std::endl; // will work only if it's a post multyply in the producer camera std::cout << "Matrix View " << view << std::endl; std::cout << _view->getCamera()->getProjectionMatrix() * offsetProjection << std::endl; #endif } else { OSG_INFO<<" GraphicsWindow has not been created successfully."<<std::endl; return 0; } } } // std::cout << "done" << std::endl; return _view.release(); } // // OSG interface to read/write from/to a file. // class ReaderWriterProducerCFG : public osgDB::ReaderWriter { public: ReaderWriterProducerCFG() { supportsExtension("cfg","Producer camera configuration file"); } virtual const char* className() const { return "Producer cfg object reader"; } virtual ReadResult readObject(const std::string& fileName, const Options* options = NULL) const { std::string ext = osgDB::getLowerCaseFileExtension(fileName); if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; osgDB::FilePathList* filePathList = 0; if(options) { filePathList = const_cast<osgDB::FilePathList*>(&(options->getDatabasePathList())); filePathList->push_back(DATADIR); } std::string path = osgDB::findDataFile(fileName); if(path.empty()) return ReadResult::FILE_NOT_FOUND; ReadResult result; osg::ref_ptr<osg::View> view = load(path, options); if(! view.valid()) result = ReadResult("Error: could not load " + path); else result = ReadResult(view.get()); if(options && filePathList) filePathList->pop_back(); return result; } }; REGISTER_OSGPLUGIN(cfg, ReaderWriterProducerCFG)
_______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
