Further work on osgShadow::GeometryOccluder
This commit is contained in:
@@ -12,6 +12,11 @@
|
||||
*/
|
||||
|
||||
#include <osgShadow/OccluderGeometry>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Geode>
|
||||
#include <osg/io_utils>
|
||||
#include <osg/TriangleFunctor>
|
||||
#include <osg/TriangleIndexFunctor>
|
||||
|
||||
using namespace osgShadow;
|
||||
|
||||
@@ -26,14 +31,215 @@ OccluderGeometry::OccluderGeometry(const OccluderGeometry& oc, const osg::CopyOp
|
||||
}
|
||||
|
||||
|
||||
void OccluderGeometry::computeOccluderGeometry(osg::Node* subgraph, float sampleRatio)
|
||||
class CollectOccludersVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
CollectOccludersVisitor(OccluderGeometry* oc, osg::Matrix* matrix, float ratio):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
|
||||
_oc(oc),
|
||||
_ratio(ratio)
|
||||
{
|
||||
if (matrix) pushMatrix(*matrix);
|
||||
}
|
||||
|
||||
void apply(osg::Node& node)
|
||||
{
|
||||
if (node.getStateSet()) pushState(node.getStateSet());
|
||||
|
||||
traverse(node);
|
||||
|
||||
if (node.getStateSet()) popState();
|
||||
}
|
||||
|
||||
void apply(osg::Transform& transform)
|
||||
{
|
||||
if (transform.getStateSet()) pushState(transform.getStateSet());
|
||||
|
||||
osg::Matrix matrix;
|
||||
if (!_matrixStack.empty()) matrix = _matrixStack.back();
|
||||
|
||||
transform.computeLocalToWorldMatrix(matrix,this);
|
||||
|
||||
pushMatrix(matrix);
|
||||
|
||||
traverse(transform);
|
||||
|
||||
popMatrix();
|
||||
|
||||
if (transform.getStateSet()) popState();
|
||||
}
|
||||
|
||||
void apply(osg::Geode& geode)
|
||||
{
|
||||
if (geode.getStateSet()) pushState(geode.getStateSet());
|
||||
|
||||
for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
|
||||
{
|
||||
osg::Drawable* drawable = geode.getDrawable(i);
|
||||
|
||||
if (drawable->getStateSet()) pushState(drawable->getStateSet());
|
||||
|
||||
apply(geode.getDrawable(i));
|
||||
|
||||
if (drawable->getStateSet()) popState();
|
||||
}
|
||||
|
||||
if (geode.getStateSet()) popState();
|
||||
}
|
||||
|
||||
void pushState(osg::StateSet* stateset)
|
||||
{
|
||||
osg::StateAttribute::GLModeValue prevBlendModeValue = _blendModeStack.empty() ? osg::StateAttribute::GLModeValue(osg::StateAttribute::INHERIT) : _blendModeStack.back();
|
||||
osg::StateAttribute::GLModeValue newBlendModeValue = stateset->getMode(GL_BLEND);
|
||||
|
||||
if (!(newBlendModeValue & osg::StateAttribute::PROTECTED) &&
|
||||
(prevBlendModeValue & osg::StateAttribute::OVERRIDE) )
|
||||
{
|
||||
newBlendModeValue = prevBlendModeValue;
|
||||
}
|
||||
|
||||
_blendModeStack.push_back(newBlendModeValue);
|
||||
}
|
||||
|
||||
void popState()
|
||||
{
|
||||
_blendModeStack.pop_back();
|
||||
}
|
||||
|
||||
void pushMatrix(osg::Matrix& matrix)
|
||||
{
|
||||
_matrixStack.push_back(matrix);
|
||||
}
|
||||
|
||||
void popMatrix()
|
||||
{
|
||||
_matrixStack.pop_back();
|
||||
}
|
||||
|
||||
void apply(osg::Drawable* drawable)
|
||||
{
|
||||
osg::StateAttribute::GLModeValue blendModeValue = _blendModeStack.empty() ? osg::StateAttribute::GLModeValue(osg::StateAttribute::INHERIT) : _blendModeStack.back();
|
||||
if (blendModeValue & osg::StateAttribute::ON)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Ignoring transparent drawable."<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
_oc->computeOccluderGeometry(drawable, (_matrixStack.empty() ? 0 : &_matrixStack.back()), _ratio);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
OccluderGeometry* _oc;
|
||||
|
||||
typedef std::vector<osg::Matrix> MatrixStack;
|
||||
typedef std::vector<osg::StateAttribute::GLModeValue> ModeStack;
|
||||
|
||||
float _ratio;
|
||||
MatrixStack _matrixStack;
|
||||
ModeStack _blendModeStack;
|
||||
|
||||
};
|
||||
|
||||
void OccluderGeometry::computeOccluderGeometry(osg::Node* subgraph, osg::Matrix* matrix, float sampleRatio)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"computeOccluderGeometry(osg::Node* subgraph, float sampleRatio)"<<std::endl;
|
||||
|
||||
CollectOccludersVisitor cov(this, matrix, sampleRatio);
|
||||
subgraph->accept(cov);
|
||||
|
||||
osg::notify(osg::NOTICE)<<"done"<<std::endl;
|
||||
}
|
||||
|
||||
void OccluderGeometry::computeOccluderGeometry(osg::Drawable* drawable, float sampleRatio)
|
||||
struct TriangleIndexCollector
|
||||
{
|
||||
OccluderGeometry::Vec3List& _vertices;
|
||||
OccluderGeometry::UIntList& _triangleIndices;
|
||||
unsigned int _baseIndex;
|
||||
|
||||
TriangleIndexCollector(OccluderGeometry::Vec3List& vertices, OccluderGeometry::UIntList& triangleIndices):
|
||||
_vertices(vertices),
|
||||
_triangleIndices(triangleIndices)
|
||||
{
|
||||
_baseIndex = _vertices.size();
|
||||
}
|
||||
|
||||
inline void operator()(unsigned int p1, unsigned int p2, unsigned int p3)
|
||||
{
|
||||
_triangleIndices.push_back(_baseIndex + p1);
|
||||
_triangleIndices.push_back(_baseIndex + p2);
|
||||
_triangleIndices.push_back(_baseIndex + p3);
|
||||
}
|
||||
|
||||
};
|
||||
typedef osg::TriangleIndexFunctor<TriangleIndexCollector> TriangleIndexCollectorFunctor;
|
||||
|
||||
struct TriangleCollector
|
||||
{
|
||||
OccluderGeometry::Vec3List& _vertices;
|
||||
OccluderGeometry::UIntList& _triangleIndices;
|
||||
|
||||
typedef std::vector<const osg::Vec3*> VertexPointers;
|
||||
VertexPointers _vertexPointers;
|
||||
|
||||
OccluderGeometry::Vec3List _tempoaryTriangleVertices;
|
||||
|
||||
TriangleCollector(OccluderGeometry::Vec3List& vertices, OccluderGeometry::UIntList& triangleIndices):
|
||||
_vertices(vertices),
|
||||
_triangleIndices(triangleIndices)
|
||||
{
|
||||
}
|
||||
|
||||
// bool intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r)
|
||||
inline void operator () (const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3, bool treatVertexDataAsTemporary)
|
||||
{
|
||||
if (treatVertexDataAsTemporary)
|
||||
{
|
||||
_tempoaryTriangleVertices.push_back(v1);
|
||||
_tempoaryTriangleVertices.push_back(v2);
|
||||
_tempoaryTriangleVertices.push_back(v3);
|
||||
}
|
||||
else
|
||||
{
|
||||
_vertexPointers.push_back(&v1);
|
||||
_vertexPointers.push_back(&v2);
|
||||
_vertexPointers.push_back(&v3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
typedef osg::TriangleFunctor<TriangleCollector> TriangleCollectorFunctor;
|
||||
|
||||
void OccluderGeometry::computeOccluderGeometry(osg::Drawable* drawable, osg::Matrix* matrix, float sampleRatio)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"computeOccluderGeometry(osg::Node* subgraph, float sampleRatio)"<<std::endl;
|
||||
if (matrix)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" matrix"<<*matrix<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" no matrix"<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void OccluderGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"drawImplementation(osg::RenderInfo& renderInfo)"<<std::endl;
|
||||
}
|
||||
|
||||
osg::BoundingBox OccluderGeometry::computeBound() const
|
||||
{
|
||||
osg::BoundingBox bb;
|
||||
for(Vec3List::const_iterator itr = _vertices.begin();
|
||||
itr != _vertices.end();
|
||||
++itr)
|
||||
{
|
||||
bb.expandBy(*itr);
|
||||
}
|
||||
return bb;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user