From 48dddc37b842a5c045e2c74862b8a9204bc0cf87 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 3 Jul 2009 05:25:08 +0000 Subject: [PATCH] Introduced a Locator callback and associated usage of this callback to provide interactive updating of the volume bounds --- src/osgVolume/Locator.cpp | 44 +++++++++++++++++++++++ src/osgVolume/RayTracedTechnique.cpp | 53 +++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/osgVolume/Locator.cpp b/src/osgVolume/Locator.cpp index 3d09026bc..77c5e75fd 100644 --- a/src/osgVolume/Locator.cpp +++ b/src/osgVolume/Locator.cpp @@ -25,6 +25,8 @@ void Locator::setTransformAsExtents(double minX, double minY, double maxX, doubl minX, minY, minZ, 1.0); _inverse.invert(_transform); + + locatorModified(); } 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; } + +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); + } + +} diff --git a/src/osgVolume/RayTracedTechnique.cpp b/src/osgVolume/RayTracedTechnique.cpp index acd0e0668..5d7446ddb 100644 --- a/src/osgVolume/RayTracedTechnique.cpp +++ b/src/osgVolume/RayTracedTechnique.cpp @@ -26,7 +26,51 @@ #include -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 _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 _texgen; + osg::observer_ptr _geometryLocator; + osg::observer_ptr _imageLocator; +}; + RayTracedTechnique::RayTracedTechnique() { @@ -132,6 +176,7 @@ void RayTracedTechnique::init() { geometryMatrix = masterLocator->getTransform(); _transform->setMatrix(geometryMatrix); + masterLocator->addCallback(new TransformLocatorCallback(_transform.get())); } osg::Matrix imageMatrix; @@ -412,6 +457,10 @@ void RayTracedTechnique::init() texgen->setMode(osg::TexGen::OBJECT_LINEAR); texgen->setPlanesFromMatrix( geometryMatrix * osg::Matrix::inverse(imageMatrix)); + osg::ref_ptr locatorCallback = new TexGenLocatorCallback(texgen, masterLocator, layerLocator); + masterLocator->addCallback(locatorCallback.get()); + layerLocator->addCallback(locatorCallback.get()); + stateset->setTextureAttributeAndModes(0, texgen, osg::StateAttribute::ON); } @@ -535,3 +584,5 @@ void RayTracedTechnique::traverse(osg::NodeVisitor& nv) } } + +} // end of osgVolume namespace \ No newline at end of file