OpenSceneGraph/include/osgShadow/OccluderGeometry

112 lines
4.1 KiB
C++

/* -*-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 OSGSHADOW_OCCLUDERGEOMETRY
#define OSGSHADOW_OCCLUDERGEOMETRY 1
#include <osg/Drawable>
#include <osg/Array>
#include <osg/PrimitiveSet>
#include <osgShadow/Export>
namespace osgShadow {
/** OccluderGeometry provides a sepecialised geometry representation of objects in scene that occlude light and therefore cast shadows.
* OccluderGeometry supports the computation of silhouette edges and shadow volume geometries, as well as use as geometry that one can rendering
* into a shadow map or end caps for the ZP+ algorithm. OccluderGeometry may be of the same resolution as an underlying geometry that it
* represents, or can be of lower resolution and combine manager seperate geometries together into a single shadow casting object.
* OccluderGeometry may be attached as UserData to Nodes or to Drawables. */
class OSGSHADOW_EXPORT OccluderGeometry : public osg::Drawable
{
public :
OccluderGeometry();
OccluderGeometry(const OccluderGeometry& oc, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
virtual Object* cloneType() const { return new OccluderGeometry(); }
virtual Object* clone(const osg::CopyOp& copyop) const { return new OccluderGeometry(*this,copyop); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const OccluderGeometry*>(obj)!=NULL; }
virtual const char* libraryName() const { return "osgShadow"; }
virtual const char* className() const { return "OccluderGeometry"; }
struct Edge
{
Edge():
_p1(0),
_p2(0),
_t1(0),
_t2(0) {}
Edge(unsigned int p1, unsigned int p2, unsigned int t1, unsigned int t2):
_p1(p1),
_p2(p2),
_t1(t1),
_t2(t2) {}
unsigned int _p1;
unsigned int _p2;
unsigned int _t1;
unsigned int _t2;
};
typedef std::vector<osg::Vec3> Vec3List;
typedef std::vector<GLuint> UIntList;
typedef std::vector<Edge> EdgeList;
/** Compute an occluder geometry containing all the geometry in specified subgraph.*/
void computeOccluderGeometry(osg::Node* subgraph, osg::Matrix* matrix=0, float sampleRatio=1.0f);
/** Compute an occluder geometry containing the geometry in specified drawable.*/
void computeOccluderGeometry(osg::Drawable* drawable, osg::Matrix* matrix=0, float sampleRatio=1.0f);
/** Render the occluder geometry. */
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
/** Compute the bounding box around occluder geometry.*/
virtual osg::BoundingBox computeBound() const;
public:
void processGeometry(osg::Drawable* drawable, osg::Matrix* matrix=0, float sampleRatio=1.0f);
protected :
virtual ~OccluderGeometry() {}
inline bool isSilhouetteEdge(const osg::Vec3& lightpos, const Edge& edge) const
{
osg::Vec3 delta(lightpos-_vertices[edge._p1]);
return ( delta * _triangleNormals[edge._t1] ) *
( delta * _triangleNormals[edge._t2] );
}
void setUpInternalStructures();
void removeDuplicateVertices();
void computeNormals();
void buildEdgeMaps();
Vec3List _vertices;
Vec3List _normals;
Vec3List _triangleNormals;
UIntList _triangleIndices;
};
}
#endif