diff --git a/include/osgShadow/OccluderGeometry b/include/osgShadow/OccluderGeometry index e24a22708..eedd8dbd3 100644 --- a/include/osgShadow/OccluderGeometry +++ b/include/osgShadow/OccluderGeometry @@ -20,6 +20,7 @@ #include + namespace osgShadow { /** OccluderGeometry provides a sepecialised geometry representation of objects in scene that occlude light and therefore cast shadows. @@ -41,29 +42,70 @@ class OSGSHADOW_EXPORT OccluderGeometry : public osg::Drawable virtual const char* className() const { return "OccluderGeometry"; } + typedef std::vector Vec3List; + typedef std::vector UIntList; + + struct Point + { + Point() {} + + UIntList _edges; + }; + + typedef std::vector PointList; + struct Edge { Edge(): _p1(0), _p2(0), - _t1(0), - _t2(0) {} + _t1(-1), + _t2(-1) {} - Edge(unsigned int p1, unsigned int p2, unsigned int t1, unsigned int t2): + Edge(unsigned int p1, unsigned int p2): _p1(p1), _p2(p2), - _t1(t1), - _t2(t2) {} + _t1(-1), + _t2(-1) + { + if (p1>p2) + { + // swap ordering so p1 is less than or equal to p2 + _p1 = p2; + _p2 = p1; + } + } + + inline bool operator < (const Edge& rhs) const + { + if (_p1 < rhs._p1) return true; + if (_p1 > rhs._p1) return false; + return (_p2 < rhs._p2); + } + + bool addTriangle(unsigned int tri) const + { + if (_t1<0) + { + _t1 = tri; + return true; + } + else if (_t2<0) + { + _t2 = tri; + return true; + } + // argg more than two triangles assigned + return false; + } unsigned int _p1; unsigned int _p2; - unsigned int _t1; - unsigned int _t2; + mutable int _t1; + mutable int _t2; }; - typedef std::vector Vec3List; - typedef std::vector UIntList; typedef std::vector EdgeList; /** Compute an occluder geometry containing all the geometry in specified subgraph.*/ @@ -96,6 +138,7 @@ class OSGSHADOW_EXPORT OccluderGeometry : public osg::Drawable void setUpInternalStructures(); void removeDuplicateVertices(); + void removeNullTriangles(); void computeNormals(); void buildEdgeMaps(); @@ -104,6 +147,9 @@ class OSGSHADOW_EXPORT OccluderGeometry : public osg::Drawable Vec3List _triangleNormals; UIntList _triangleIndices; + PointList _points; + EdgeList _edges; + }; } diff --git a/src/osgShadow/OccluderGeometry.cpp b/src/osgShadow/OccluderGeometry.cpp index 0213f1b7e..3090d1337 100644 --- a/src/osgShadow/OccluderGeometry.cpp +++ b/src/osgShadow/OccluderGeometry.cpp @@ -301,10 +301,14 @@ void OccluderGeometry::processGeometry(osg::Drawable* drawable, osg::Matrix* mat void OccluderGeometry::setUpInternalStructures() { removeDuplicateVertices(); + + removeNullTriangles(); computeNormals(); buildEdgeMaps(); + + dirtyBound(); dirtyDisplayList(); } @@ -427,6 +431,46 @@ void OccluderGeometry::removeDuplicateVertices() osg::notify(osg::NOTICE)<<"OccluderGeometry::removeDuplicates() after = "<<_vertices.size()< EdgeSet; + EdgeSet edgeSet; + + unsigned int numTriangleErrors = 0; + unsigned int triNo=0; + for(UIntList::iterator titr = _triangleIndices.begin(); + titr != _triangleIndices.end(); + ++triNo) + { + GLuint p1 = *titr++; + GLuint p2 = *titr++; + GLuint p3 = *titr++; + + { + Edge edge12(p1,p2); + EdgeSet::iterator itr = edgeSet.find(edge12); + if (itr == edgeSet.end()) + { + if (!edge12.addTriangle(triNo)) ++numTriangleErrors; + edgeSet.insert(edge12); + } + else + { + if (!itr->addTriangle(triNo)) ++numTriangleErrors; + } + } + + { + Edge edge23(p2,p3); + EdgeSet::iterator itr = edgeSet.find(edge23); + if (itr == edgeSet.end()) + { + if (!edge23.addTriangle(triNo)) ++numTriangleErrors; + edgeSet.insert(edge23); + } + else + { + if (!itr->addTriangle(triNo)) ++numTriangleErrors; + } + } + + { + Edge edge31(p3,p1); + EdgeSet::iterator itr = edgeSet.find(edge31); + if (itr == edgeSet.end()) + { + if (!edge31.addTriangle(triNo)) ++numTriangleErrors; + + edgeSet.insert(edge31); + } + else + { + if (!itr->addTriangle(triNo)) ++numTriangleErrors; + } + } + } + + _edges.clear(); + _edges.reserve(edgeSet.size()); + + unsigned int numEdgesWithNoTriangles = 0; + unsigned int numEdgesWithOneTriangles = 0; + unsigned int numEdgesWithTwoTriangles = 0; + + for(EdgeSet::iterator eitr = edgeSet.begin(); + eitr != edgeSet.end(); + ++eitr) + { + _edges.push_back(*eitr); + unsigned int numTriangles = ((eitr->_t1>=0)? 1:0) + ((eitr->_t2>=0)? 1:0); + switch(numTriangles) + { + case(0): ++numEdgesWithNoTriangles; break; + case(1): ++numEdgesWithOneTriangles; break; + default: ++numEdgesWithTwoTriangles; break; + } + } + + osg::notify(osg::NOTICE)<<"Num of indices "<<_triangleIndices.size()<