Hi Filip,
I've been wondering about the issue with binary compatibility - and
adding a virtual function breaks binary compatibility which is bad
news for 2.2.1. It occurred to me that the only way not to break
binary compatibility would be to modify the existing View::addSlave
method so that it copied it's Camera's subgraph from the master
Camera's subgraph.
I have modified and checked in the modified View.cpp, its also
attached. I didn't have any example code to reproduce the original so
could you try at your end?
Cheers,
Robert.
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRA;NTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osg/View>
#include <osg/Notify>
#include <osg/TexEnv>
#include <osg/DeleteHandler>
using namespace osg;
View::View():
Object(true)
{
// osg::notify(osg::NOTICE)<<"Constructing osg::View"<<std::endl;
setLightingMode(HEADLIGHT);
_camera = new osg::Camera;
_camera->setView(this);
double height = osg::DisplaySettings::instance()->getScreenHeight();
double width = osg::DisplaySettings::instance()->getScreenWidth();
double distance = osg::DisplaySettings::instance()->getScreenDistance();
double vfov = osg::RadiansToDegrees(atan2(height/2.0f,distance)*2.0);
_camera->setProjectionMatrixAsPerspective( vfov, width/height, 1.0f,10000.0f);
_camera->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.4f, 1.0f));
osg::StateSet* stateset = _camera->getOrCreateStateSet();
stateset->setGlobalDefaults();
}
View::View(const osg::View& view, const osg::CopyOp& copyop):
Object(view,copyop),
_lightingMode(view._lightingMode),
_light(view._light),
_camera(view._camera),
_slaves(view._slaves)
{
}
View::~View()
{
osg::notify(osg::INFO)<<"Destructing osg::View"<<std::endl;
if (_camera.valid())
{
_camera->setView(0);
_camera->setCullCallback(0);
}
// detatch the cameras from this View to prevent dangling pointers
for(Slaves::iterator itr = _slaves.begin();
itr != _slaves.end();
++itr)
{
Slave& cd = *itr;
cd._camera->setView(0);
cd._camera->setCullCallback(0);
}
_camera = 0;
_slaves.clear();
_light = 0;
#if 0
if (osg::Referenced::getDeleteHandler())
{
// osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
osg::Referenced::getDeleteHandler()->flushAll();
}
#endif
osg::notify(osg::INFO)<<"Done destructing osg::View"<<std::endl;
}
void View::take(osg::View& rhs)
{
// copy across the contents first
_lightingMode = rhs._lightingMode;
_light = rhs._light;
_camera = rhs._camera;
_slaves = rhs._slaves;
// update the cameras so they all now see this View as their parent View
if (_camera.valid()) _camera->setView(this);
for(unsigned int i=0; i<_slaves.size(); ++i)
{
if (_slaves[i]._camera.valid()) _slaves[i]._camera->setView(this);
}
// then clear the passing in view.
rhs._light = 0;
rhs._camera = 0;
rhs._slaves.clear();
}
void View::setLightingMode(LightingMode lightingMode)
{
_lightingMode = lightingMode;
if (_lightingMode != NO_LIGHT && !_light)
{
_light = new osg::Light;
_light->setThreadSafeRefUnref(true);
_light->setLightNum(0);
_light->setAmbient(Vec4(0.00f,0.0f,0.00f,1.0f));
_light->setDiffuse(Vec4(0.8f,0.8f,0.8f,1.0f));
_light->setSpecular(Vec4(1.0f,1.0f,1.0f,1.0f));
}
}
void View::setCamera(osg::Camera* camera)
{
if (_camera.valid()) _camera->setView(0);
_camera = camera;
if (_camera.valid())
{
_camera->setView(this);
_camera->setRenderer(createRenderer(camera));
}
}
void View::updateSlaves()
{
for(unsigned int i=0; i<_slaves.size(); ++i)
{
updateSlave(i);
}
}
void View::updateSlave(unsigned int i)
{
if (i >= _slaves.size() || !_camera) return;
Slave& slave = _slaves[i];
if (slave._camera->getReferenceFrame()==osg::Transform::RELATIVE_RF)
{
slave._camera->setProjectionMatrix(_camera->getProjectionMatrix() * slave._projectionOffset);
slave._camera->setViewMatrix(_camera->getViewMatrix() * slave._viewOffset);
}
slave._camera->inheritCullSettings(*_camera);
if (slave._camera->getInheritanceMask() & osg::CullSettings::CLEAR_COLOR) slave._camera->setClearColor(_camera->getClearColor());
}
bool View::addSlave(osg::Camera* camera, const osg::Matrix& projectionOffset, const osg::Matrix& viewOffset, bool useMastersSceneData)
{
if (!camera) return false;
camera->setView(this);
unsigned int i = _slaves.size();
if (useMastersSceneData)
{
camera->removeChildren(0,camera->getNumChildren());
if (_camera.valid())
{
for(unsigned int i=0; _camera->getNumChildren(); ++i)
{
camera->addChild(_camera->getChild(i));
}
}
}
_slaves.push_back(Slave(camera, projectionOffset, viewOffset, useMastersSceneData));
updateSlave(i);
camera->setRenderer(createRenderer(camera));
return true;
}
bool View::removeSlave(unsigned int pos)
{
if (pos >= _slaves.size()) return false;
_slaves[pos]._camera->setView(0);
_slaves[pos]._camera->setCullCallback(0);
_slaves.erase(_slaves.begin()+pos);
return true;
}
View::Slave * View::findSlaveForCamera(osg::Camera* camera)
{
unsigned int i = findSlaveIndexForCamera(camera);
if (i >= getNumSlaves()) return (NULL);
return &(_slaves[i]);
}
unsigned int View::findSlaveIndexForCamera(osg::Camera* camera)
{
if (_camera == camera) return _slaves.size();
for(unsigned int i=0; i<_slaves.size(); ++i)
{
if (_slaves[i]._camera == camera) return (i);
}
return _slaves.size();
}
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org