Fixed handling of Locator's with negative extents

This commit is contained in:
Robert Osfield 2016-11-11 13:54:15 +00:00
parent fa27a1f3ed
commit b58048e43b
4 changed files with 37 additions and 1 deletions

View File

@ -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

View File

@ -14,6 +14,7 @@
#include <osgVolume/Locator>
#include <osg/io_utils>
#include <osg/Notify>
#include <osg/FrontFace>
#include <list>
@ -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<osg::FrontFace*>(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());
}
}

View File

@ -497,6 +497,7 @@ void MultipassTechnique::init()
{
geometryMatrix = masterLocator->getTransform();
_transform->setMatrix(geometryMatrix);
masterLocator->applyAppropriateFrontFace(_transform->getOrCreateStateSet());
masterLocator->addCallback(new TransformLocatorCallback(_transform.get()));
}

View File

@ -134,6 +134,7 @@ void RayTracedTechnique::init()
{
geometryMatrix = masterLocator->getTransform();
_transform->setMatrix(geometryMatrix);
masterLocator->applyAppropriateFrontFace(_transform->getOrCreateStateSet());
masterLocator->addCallback(new TransformLocatorCallback(_transform.get()));
}