diff --git a/include/osgVolume/Locator b/include/osgVolume/Locator index 07da1bd55..7014c98f8 100644 --- a/include/osgVolume/Locator +++ b/include/osgVolume/Locator @@ -67,6 +67,12 @@ class OSGVOLUME_EXPORT Locator : public osg::Object bool computeLocalBounds(osg::Vec3d& bottomLeft, osg::Vec3d& topRight) const; bool computeLocalBounds(Locator& source, osg::Vec3d& bottomLeft, osg::Vec3d& topRight) const; + /** Return true if the axis of the Locator are inverted requiring the faces of any cubes used from rendering to be flipped to ensure the correct front/back face is used.*/ + bool inverted() const; + + /** apply the appropriate FrontFace setting to provided StateSet to ensure that the rendering of hull of the volume is the correct orientation.*/ + void applyAppropriateFrontFace(osg::StateSet* ss) const; + /** Callback interface for enabling the monitoring of changes to the Locator.*/ class LocatorCallback : virtual public osg::Object diff --git a/src/osgVolume/Locator.cpp b/src/osgVolume/Locator.cpp index d6061d9a1..2de869d16 100644 --- a/src/osgVolume/Locator.cpp +++ b/src/osgVolume/Locator.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -223,6 +224,28 @@ void Locator::locatorModified() } +bool Locator::inverted() const +{ + osg::Vec3d xAxis(_transform(0,0), _transform(1,0), _transform(2,0)); + osg::Vec3d yAxis(_transform(0,1), _transform(1,1), _transform(2,1)); + osg::Vec3d zAxis(_transform(0,2), _transform(1,2), _transform(2,2)); + float volume = (xAxis^yAxis)*zAxis; + return volume<0.0; +} + +void Locator::applyAppropriateFrontFace(osg::StateSet* ss) const +{ + osg::StateAttribute* sa = ss->getAttribute(osg::StateAttribute::FRONTFACE); + osg::FrontFace* ff = dynamic_cast(sa); + if (!ff) + { + ff = new osg::FrontFace; + ss->setAttribute(ff); + } + ff->setMode( inverted() ? osg::FrontFace::CLOCKWISE : osg::FrontFace::COUNTER_CLOCKWISE); +} + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // TransformLocatorCallback @@ -233,7 +256,12 @@ TransformLocatorCallback::TransformLocatorCallback(osg::MatrixTransform* transfo void TransformLocatorCallback::locatorModified(Locator* locator) { - if (_transform.valid()) _transform->setMatrix(locator->getTransform()); + if (_transform.valid()) + { + locator->applyAppropriateFrontFace(_transform->getOrCreateStateSet()); + + _transform->setMatrix(locator->getTransform()); + } } diff --git a/src/osgVolume/MultipassTechnique.cpp b/src/osgVolume/MultipassTechnique.cpp index 30a238216..e0e7ab538 100644 --- a/src/osgVolume/MultipassTechnique.cpp +++ b/src/osgVolume/MultipassTechnique.cpp @@ -497,6 +497,7 @@ void MultipassTechnique::init() { geometryMatrix = masterLocator->getTransform(); _transform->setMatrix(geometryMatrix); + masterLocator->applyAppropriateFrontFace(_transform->getOrCreateStateSet()); masterLocator->addCallback(new TransformLocatorCallback(_transform.get())); } diff --git a/src/osgVolume/RayTracedTechnique.cpp b/src/osgVolume/RayTracedTechnique.cpp index 787e10291..6893cb902 100644 --- a/src/osgVolume/RayTracedTechnique.cpp +++ b/src/osgVolume/RayTracedTechnique.cpp @@ -134,6 +134,7 @@ void RayTracedTechnique::init() { geometryMatrix = masterLocator->getTransform(); _transform->setMatrix(geometryMatrix); + masterLocator->applyAppropriateFrontFace(_transform->getOrCreateStateSet()); masterLocator->addCallback(new TransformLocatorCallback(_transform.get())); }