Introduced a Locator callback and associated usage of this callback to provide interactive updating of the volume bounds

This commit is contained in:
Robert Osfield 2009-07-03 05:25:08 +00:00
parent 23dec86e22
commit 48dddc37b8
2 changed files with 96 additions and 1 deletions

View File

@ -25,6 +25,8 @@ void Locator::setTransformAsExtents(double minX, double minY, double maxX, doubl
minX, minY, minZ, 1.0); minX, minY, minZ, 1.0);
_inverse.invert(_transform); _inverse.invert(_transform);
locatorModified();
} }
bool Locator::convertLocalToModel(const osg::Vec3d& local, osg::Vec3d& world) const bool Locator::convertLocalToModel(const osg::Vec3d& local, osg::Vec3d& world) const
@ -165,3 +167,45 @@ bool Locator::computeLocalBounds(osg::Vec3d& bottomLeft, osg::Vec3d& topRight) c
return true; return true;
} }
void Locator::addCallback(LocatorCallback* callback)
{
// check if callback is already attached, if so just return early
for(LocatorCallbacks::iterator itr = _locatorCallbacks.begin();
itr != _locatorCallbacks.end();
++itr)
{
if (*itr == callback)
{
return;
}
}
// callback is not attached so now attach it.
_locatorCallbacks.push_back(callback);
}
void Locator::removeCallback(LocatorCallback* callback)
{
// checl if callback is attached, if so erase it.
for(LocatorCallbacks::iterator itr = _locatorCallbacks.begin();
itr != _locatorCallbacks.end();
++itr)
{
if (*itr == callback)
{
_locatorCallbacks.erase(itr);
}
}
}
void Locator::locatorModified()
{
for(LocatorCallbacks::iterator itr = _locatorCallbacks.begin();
itr != _locatorCallbacks.end();
++itr)
{
(*itr)->locatorModified(this);
}
}

View File

@ -26,7 +26,51 @@
#include <osgDB/ReadFile> #include <osgDB/ReadFile>
using namespace osgVolume; namespace osgVolume
{
class TransformLocatorCallback : public Locator::LocatorCallback
{
public:
TransformLocatorCallback(osg::MatrixTransform* transform): _transform(transform) {}
void locatorModified(Locator* locator)
{
if (_transform.valid()) _transform->setMatrix(locator->getTransform());
}
protected:
osg::observer_ptr<osg::MatrixTransform> _transform;
};
class TexGenLocatorCallback : public Locator::LocatorCallback
{
public:
TexGenLocatorCallback(osg::TexGen* texgen, Locator* geometryLocator, Locator* imageLocator):
_texgen(texgen),
_geometryLocator(geometryLocator),
_imageLocator(imageLocator) {}
void locatorModified(Locator*)
{
if (!_texgen || !_geometryLocator || !_imageLocator) return;
_texgen->setPlanesFromMatrix(
_geometryLocator->getTransform() *
osg::Matrix::inverse(_imageLocator->getTransform()));
}
protected:
osg::observer_ptr<osg::TexGen> _texgen;
osg::observer_ptr<osgVolume::Locator> _geometryLocator;
osg::observer_ptr<osgVolume::Locator> _imageLocator;
};
RayTracedTechnique::RayTracedTechnique() RayTracedTechnique::RayTracedTechnique()
{ {
@ -132,6 +176,7 @@ void RayTracedTechnique::init()
{ {
geometryMatrix = masterLocator->getTransform(); geometryMatrix = masterLocator->getTransform();
_transform->setMatrix(geometryMatrix); _transform->setMatrix(geometryMatrix);
masterLocator->addCallback(new TransformLocatorCallback(_transform.get()));
} }
osg::Matrix imageMatrix; osg::Matrix imageMatrix;
@ -412,6 +457,10 @@ void RayTracedTechnique::init()
texgen->setMode(osg::TexGen::OBJECT_LINEAR); texgen->setMode(osg::TexGen::OBJECT_LINEAR);
texgen->setPlanesFromMatrix( geometryMatrix * osg::Matrix::inverse(imageMatrix)); texgen->setPlanesFromMatrix( geometryMatrix * osg::Matrix::inverse(imageMatrix));
osg::ref_ptr<TexGenLocatorCallback> locatorCallback = new TexGenLocatorCallback(texgen, masterLocator, layerLocator);
masterLocator->addCallback(locatorCallback.get());
layerLocator->addCallback(locatorCallback.get());
stateset->setTextureAttributeAndModes(0, texgen, osg::StateAttribute::ON); stateset->setTextureAttributeAndModes(0, texgen, osg::StateAttribute::ON);
} }
@ -535,3 +584,5 @@ void RayTracedTechnique::traverse(osg::NodeVisitor& nv)
} }
} }
} // end of osgVolume namespace