Polytope
Go to the documentation of this file.
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_POLYTOPE
#define OSG_POLYTOPE 1
#include <osg/Plane>
#include <osg/fast_back_stack>
namespace osg {
class OSG_EXPORT Polytope
{
public:
typedef unsigned int ClippingMask;
typedef std::vector<Plane> PlaneList;
typedef std::vector<Vec3> VertexList;
typedef fast_back_stack<ClippingMask> MaskStack;
inline Polytope() {setupMask();}
inline Polytope(const Polytope& cv) :
_maskStack(cv._maskStack),
_resultMask(cv._resultMask),
_planeList(cv._planeList),
_referenceVertexList(cv._referenceVertexList) {}
inline Polytope(const PlaneList& pl) : _planeList(pl) {setupMask();}
inline ~Polytope() {}
inline void clear() { _planeList.clear(); setupMask(); }
inline Polytope& operator = (const Polytope& cv)
{
if (&cv==this) return *this;
_maskStack = cv._maskStack;
_resultMask = cv._resultMask;
_planeList = cv._planeList;
_referenceVertexList = cv._referenceVertexList;
return *this;
}
void setToUnitFrustum(bool withNear=true, bool withFar=true)
{
_planeList.clear();
_planeList.push_back(Plane(1.0,0.0,0.0,1.0)); // left plane.
_planeList.push_back(Plane(-1.0,0.0,0.0,1.0)); // right plane.
_planeList.push_back(Plane(0.0,1.0,0.0,1.0)); // bottom plane.
_planeList.push_back(Plane(0.0,-1.0,0.0,1.0)); // top plane.
if (withNear) _planeList.push_back(Plane(0.0,0.0,1.0,1.0)); // near plane
if (withFar) _planeList.push_back(Plane(0.0,0.0,-1.0,1.0)); // far plane
setupMask();
}
void setToBoundingBox(const BoundingBox& bb)
{
_planeList.clear();
_planeList.push_back(Plane(1.0,0.0,0.0,-bb.xMin())); // left plane.
_planeList.push_back(Plane(-1.0,0.0,0.0,bb.xMax())); // right plane.
_planeList.push_back(Plane(0.0,1.0,0.0,-bb.yMin())); // bottom plane.
_planeList.push_back(Plane(0.0,-1.0,0.0,bb.yMax())); // top plane.
_planeList.push_back(Plane(0.0,0.0,1.0,-bb.zMin())); // near plane
_planeList.push_back(Plane(0.0,0.0,-1.0,bb.zMax())); // far plane
setupMask();
}
inline void setAndTransformProvidingInverse(const Polytope& pt, const osg::Matrix& matrix)
{
_referenceVertexList = pt._referenceVertexList;
unsigned int resultMask = pt._maskStack.back();
if (resultMask==0)
{
_maskStack.back() = 0;
_resultMask = 0;
_planeList.clear();
return;
}
ClippingMask selector_mask = 0x1;
unsigned int numActivePlanes = 0;
// count number of active planes.
PlaneList::const_iterator itr;
for(itr=pt._planeList.begin();
itr!=pt._planeList.end();
++itr)
{
if (resultMask&selector_mask) ++numActivePlanes;
selector_mask <<= 1;
}
_planeList.resize(numActivePlanes);
_resultMask = 0;
selector_mask = 0x1;
unsigned int index = 0;
for(itr=pt._planeList.begin();
itr!=pt._planeList.end();
++itr)
{
if (resultMask&selector_mask)
{
_planeList[index] = *itr;
_planeList[index++].transformProvidingInverse(matrix);
_resultMask = (_resultMask<<1) | 1;
}
selector_mask <<= 1;
}
_maskStack.back() = _resultMask;
}
inline void set(const PlaneList& pl) { _planeList = pl; setupMask(); }
inline void add(const osg::Plane& pl) { _planeList.push_back(pl); setupMask(); }
inline void flip()
{
for(PlaneList::iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
itr->flip();
}
}
inline bool empty() const { return _planeList.empty(); }
inline PlaneList& getPlaneList() { return _planeList; }
inline const PlaneList& getPlaneList() const { return _planeList; }
inline void setReferenceVertexList(VertexList& vertices) { _referenceVertexList=vertices; }
inline VertexList& getReferenceVertexList() { return _referenceVertexList; }
inline const VertexList& getReferenceVertexList() const { return _referenceVertexList; }
inline void setupMask()
{
_resultMask = 0;
for(unsigned int i=0;i<_planeList.size();++i)
{
_resultMask = (_resultMask<<1) | 1;
}
_maskStack.push_back(_resultMask);
}
inline ClippingMask& getCurrentMask() { return _maskStack.back(); }
inline ClippingMask getCurrentMask() const { return _maskStack.back(); }
inline void setResultMask(ClippingMask mask) { _resultMask=mask; }
inline ClippingMask getResultMask() const { return _resultMask; }
MaskStack& getMaskStack() { return _maskStack; }
const MaskStack& getMaskStack() const { return _maskStack; }
inline void pushCurrentMask()
{
_maskStack.push_back(_resultMask);
}
inline void popCurrentMask()
{
_maskStack.pop_back();
}
inline bool contains(const osg::Vec3& v) const
{
if (!_maskStack.back()) return true;
unsigned int selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if ((_maskStack.back()&selector_mask) && (itr->distance(v)<0.0f)) return false;
selector_mask <<= 1;
}
return true;
}
inline bool contains(const std::vector<Vec3>& vertices)
{
if (!_maskStack.back()) return true;
_resultMask = _maskStack.back();
for(std::vector<Vec3>::const_iterator vitr = vertices.begin();
vitr != vertices.end();
++vitr)
{
const osg::Vec3& v = *vitr;
bool outside = false;
ClippingMask selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end() && !outside;
++itr)
{
if ((_maskStack.back()&selector_mask) && (itr->distance(v)<0.0f)) outside = true;
selector_mask <<= 1;
}
if (!outside) return true;
}
return false;
}
inline bool contains(const osg::BoundingSphere& bs)
{
if (!_maskStack.back()) return true;
_resultMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (_resultMask&selector_mask)
{
int res=itr->intersect(bs);
if (res<0) return false; // outside clipping set.
else if (res>0) _resultMask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
inline bool contains(const osg::BoundingBox& bb)
{
if (!_maskStack.back()) return true;
_resultMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (_resultMask&selector_mask)
{
int res=itr->intersect(bb);
if (res<0) return false; // outside clipping set.
else if (res>0) _resultMask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
inline bool containsAllOf(const std::vector<Vec3>& vertices)
{
if (!_maskStack.back()) return false;
_resultMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (_resultMask&selector_mask)
{
int res=itr->intersect(vertices);
if (res<1) return false; // intersects, or is below plane.
_resultMask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
inline bool containsAllOf(const osg::BoundingSphere& bs)
{
if (!_maskStack.back()) return false;
_resultMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (_resultMask&selector_mask)
{
int res=itr->intersect(bs);
if (res<1) return false; // intersects, or is below plane.
_resultMask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
inline bool containsAllOf(const osg::BoundingBox& bb)
{
if (!_maskStack.back()) return false;
_resultMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (_resultMask&selector_mask)
{
int res=itr->intersect(bb);
if (res<1) return false; // intersects, or is below plane.
_resultMask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
bool contains(const osg::Vec3f& v0, const osg::Vec3f& v1, const osg::Vec3f& v2) const;
inline void transform(const osg::Matrix& matrix)
{
osg::Matrix inverse;
inverse.invert(matrix);
transformProvidingInverse(inverse);
}
inline void transformProvidingInverse(const osg::Matrix& matrix)
{
if (!_maskStack.back()) return;
_resultMask = _maskStack.back();
ClippingMask selector_mask = 0x1;
for(PlaneList::iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (_resultMask&selector_mask)
{
itr->transformProvidingInverse(matrix);
}
selector_mask <<= 1;
}
}
protected:
MaskStack _maskStack;
ClippingMask _resultMask;
PlaneList _planeList;
VertexList _referenceVertexList;
};
} // end of namespace
#endif
Plane
osg::BoundingBoxImpl::xMax
value_type & xMax()
Definition BoundingBox:116
osg::BoundingBoxImpl::yMin
value_type & yMin()
Definition BoundingBox:110
osg::BoundingBoxImpl::xMin
value_type & xMin()
Definition BoundingBox:107
osg::BoundingBoxImpl::zMin
value_type & zMin()
Definition BoundingBox:113
osg::BoundingBoxImpl::zMax
value_type & zMax()
Definition BoundingBox:122
osg::BoundingBoxImpl::yMax
value_type & yMax()
Definition BoundingBox:119
osg::Matrixd::invert
bool invert(const Matrixd &rhs)
Definition Matrixd:233
osg::Plane
A plane class. It can be used to represent an infinite plane.
Definition Plane:34
osg::Polytope::containsAllOf
bool containsAllOf(const osg::BoundingSphere &bs)
Definition Polytope:316
osg::Polytope::_resultMask
ClippingMask _resultMask
Definition Polytope:402
osg::Polytope::contains
bool contains(const osg::Vec3f &v0, const osg::Vec3f &v1, const osg::Vec3f &v2) const
osg::Polytope::getResultMask
ClippingMask getResultMask() const
Definition Polytope:178
osg::Polytope::setReferenceVertexList
void setReferenceVertexList(VertexList &vertices)
Definition Polytope:155
osg::Polytope::getReferenceVertexList
const VertexList & getReferenceVertexList() const
Definition Polytope:159
osg::Polytope::pushCurrentMask
void pushCurrentMask()
Definition Polytope:185
osg::Polytope::set
void set(const PlaneList &pl)
Definition Polytope:132
osg::Polytope::Polytope
Polytope()
Definition Polytope:35
osg::Polytope::contains
bool contains(const osg::Vec3 &v) const
Definition Polytope:196
osg::Polytope::getPlaneList
PlaneList & getPlaneList()
Definition Polytope:150
osg::Polytope::Polytope
Polytope(const PlaneList &pl)
Definition Polytope:43
osg::Polytope::getMaskStack
MaskStack & getMaskStack()
Definition Polytope:180
osg::Polytope::~Polytope
~Polytope()
Definition Polytope:45
osg::Polytope::setAndTransformProvidingInverse
void setAndTransformProvidingInverse(const Polytope &pt, const osg::Matrix &matrix)
Definition Polytope:85
osg::Polytope::contains
bool contains(const osg::BoundingSphere &bs)
Definition Polytope:243
osg::Polytope::contains
bool contains(const std::vector< Vec3 > &vertices)
Definition Polytope:212
osg::Polytope::ClippingMask
unsigned int ClippingMask
Definition Polytope:30
osg::Polytope::setupMask
void setupMask()
Definition Polytope:162
osg::Polytope::setResultMask
void setResultMask(ClippingMask mask)
Definition Polytope:176
osg::Polytope::add
void add(const osg::Plane &pl)
Definition Polytope:135
osg::Polytope::_planeList
PlaneList _planeList
Definition Polytope:403
osg::Polytope::_maskStack
MaskStack _maskStack
Definition Polytope:401
osg::Polytope::getCurrentMask
ClippingMask getCurrentMask() const
Definition Polytope:174
osg::Polytope::contains
bool contains(const osg::BoundingBox &bb)
Definition Polytope:270
osg::Polytope::popCurrentMask
void popCurrentMask()
Definition Polytope:190
osg::Polytope::setToBoundingBox
void setToBoundingBox(const BoundingBox &bb)
Definition Polytope:73
osg::Polytope::flip
void flip()
Definition Polytope:138
osg::Polytope::containsAllOf
bool containsAllOf(const std::vector< Vec3 > &vertices)
Definition Polytope:293
osg::Polytope::_referenceVertexList
VertexList _referenceVertexList
Definition Polytope:404
osg::Polytope::clear
void clear()
Definition Polytope:47
osg::Polytope::transform
void transform(const osg::Matrix &matrix)
Definition Polytope:371
osg::Polytope::VertexList
std::vector< Vec3 > VertexList
Definition Polytope:32
osg::Polytope::Polytope
Polytope(const Polytope &cv)
Definition Polytope:37
osg::Polytope::getReferenceVertexList
VertexList & getReferenceVertexList()
Definition Polytope:157
osg::Polytope::transformProvidingInverse
void transformProvidingInverse(const osg::Matrix &matrix)
Definition Polytope:380
osg::Polytope::containsAllOf
bool containsAllOf(const osg::BoundingBox &bb)
Definition Polytope:339
osg::Polytope::PlaneList
std::vector< Plane > PlaneList
Definition Polytope:31
osg::Polytope::getMaskStack
const MaskStack & getMaskStack() const
Definition Polytope:182
osg::Polytope::MaskStack
fast_back_stack< ClippingMask > MaskStack
Definition Polytope:33
osg::Polytope::getPlaneList
const PlaneList & getPlaneList() const
Definition Polytope:152
osg::Polytope::getCurrentMask
ClippingMask & getCurrentMask()
Definition Polytope:172
osg::Polytope::setToUnitFrustum
void setToUnitFrustum(bool withNear=true, bool withFar=true)
Definition Polytope:60
osg::Polytope::empty
bool empty() const
Definition Polytope:148
osg::Vec3f
Definition Vec3f:29
osg::fast_back_stack
Definition fast_back_stack:31
osg::fast_back_stack::back
T & back()
Definition fast_back_stack:54
fast_back_stack
osg
Definition AlphaFunc:19
osg::Vec3
Vec3f Vec3
Definition Vec3:21
osg::BoundingBox
BoundingBoxd BoundingBox
Definition BoundingBox:257
osg::BoundingSphere
BoundingSphered BoundingSphere
Definition BoundingSphere:314
osg::Matrix
Matrixd Matrix
Definition Matrix:27
OSG_EXPORT
#define OSG_EXPORT
Definition osg/Export:39