More clean up for synch with 0.8.42
This commit is contained in:
177
include/osg/ClippingVolume
Normal file
177
include/osg/ClippingVolume
Normal file
@@ -0,0 +1,177 @@
|
||||
#ifndef OSG_CLIPPINGVOLUME
|
||||
#define OSG_CLIPPINGVOLUME 1
|
||||
|
||||
#include <osg/Plane>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** A ClippingVolume class for represecting convex clipping volumes made up.*/
|
||||
class SG_EXPORT ClippingVolume
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
typedef std::vector<osg::Plane> PlaneList;
|
||||
|
||||
inline ClippingVolume() {setupMask();}
|
||||
|
||||
inline ClippingVolume(const ClippingVolume& cv) : _localMask(cv._localMask), _planeList(cv._planeList) {}
|
||||
|
||||
inline ClippingVolume(const PlaneList& pl) : _planeList(pl) {setupMask();}
|
||||
|
||||
inline ~ClippingVolume() {}
|
||||
|
||||
inline void clear() { _planeList.clear(); setupMask(); }
|
||||
|
||||
inline ClippingVolume& operator = (const ClippingVolume& cv)
|
||||
{
|
||||
if (&cv==this) return *this;
|
||||
_localMask = cv._localMask;
|
||||
_planeList = cv._planeList;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void set(const ClippingVolume& cs) { _planeList = cs._planeList; setupMask(); }
|
||||
|
||||
inline void set(const PlaneList& pl) { _planeList = pl; setupMask(); }
|
||||
|
||||
inline void add(const osg::Plane& pl) { _planeList.push_back(pl); setupMask(); }
|
||||
|
||||
inline PlaneList& getPlaneList() { return _planeList; }
|
||||
|
||||
inline const PlaneList& getPlaneList() const { return _planeList; }
|
||||
|
||||
inline void setupMask()
|
||||
{
|
||||
_localMask = 0;
|
||||
for(unsigned int i=0;i<_planeList.size();++i)
|
||||
{
|
||||
_localMask = (_localMask<<1) | 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Check whether a vertex is contained with clipping set.*/
|
||||
inline const bool contains(const osg::Vec3& v) const
|
||||
{
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->distance(v)<0.0f) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether any part of a bounding sphere is contained within clipping set.
|
||||
Using a mask to determine which planes should be used for the check, and
|
||||
modifying the mask to turn off planes which wouldn't contribute to clipping
|
||||
of any internal objects. This feature is used in osgUtil::CullVisitor
|
||||
to prevent redundent plane checking.*/
|
||||
inline const bool contains(const osg::BoundingSphere& bs,unsigned int& mask) const
|
||||
{
|
||||
if (!(mask & _localMask)) return true;
|
||||
|
||||
unsigned int selector_mask = 0x1;
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (mask&selector_mask)
|
||||
{
|
||||
int res=itr->intersect(bs);
|
||||
if (res<0) return false; // outside clipping set.
|
||||
else if (res>0) mask ^= selector_mask; // subsequent checks against this plane not required.
|
||||
}
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether any part of a bounding sphere is contained within clipping set.*/
|
||||
inline const bool contains(const osg::BoundingSphere& bs) const
|
||||
{
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->intersect(bs)<0) return false; // outside clipping set.
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether any part of a bounding box is contained within clipping set.
|
||||
Using a mask to determine which planes should be used for the check, and
|
||||
modifying the mask to turn off planes which wouldn't contribute to clipping
|
||||
of any internal objects. This feature is used in osgUtil::CullVisitor
|
||||
to prevent redundent plane checking.*/
|
||||
inline const bool contains(const osg::BoundingBox& bb,unsigned int& mask) const
|
||||
{
|
||||
if (!(mask & _localMask)) return true;
|
||||
|
||||
unsigned int selector_mask = 0x1;
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (mask&selector_mask)
|
||||
{
|
||||
int res=itr->intersect(bb);
|
||||
if (res<0) return false; // outside clipping set.
|
||||
else if (res>0) mask ^= selector_mask; // subsequent checks against this plane not required.
|
||||
}
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether any part of a bounding box is contained within clipping set.*/
|
||||
inline const bool contains(const osg::BoundingBox& bb) const
|
||||
{
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->intersect(bb)<0) return false; // outside clipping set.
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** Transform the clipping set by matrix. Note, this operations carries out
|
||||
* the calculation of the inverse of the matrix since to transforms
|
||||
* planes must be multiplied my the inverse transposed. This
|
||||
* make this operation expensive. If the inverse has been already
|
||||
* calculated elsewhere then use transformProvidingInverse() instead.
|
||||
* See http://www.worldserver.com/turk/computergraphics/NormalTransformations.pdf*/
|
||||
inline void transform(const osg::Matrix& matrix)
|
||||
{
|
||||
osg::Matrix inverse;
|
||||
inverse.invert(matrix);
|
||||
transformProvidingInverse(inverse);
|
||||
}
|
||||
|
||||
/** Transform the clipping set by provide a pre inverted matrix.
|
||||
* see transform for details. */
|
||||
inline void transformProvidingInverse(const osg::Matrix& matrix)
|
||||
{
|
||||
for(PlaneList::iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
itr->transformProvidingInverse(matrix);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
unsigned int _localMask;
|
||||
PlaneList _planeList;
|
||||
|
||||
};
|
||||
|
||||
}; // end of namespace
|
||||
#endif
|
||||
Reference in New Issue
Block a user