OSG  3.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OccluderGeometry.h
Go to the documentation of this file.
1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version. The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * OpenSceneGraph Public License for more details.
12 */
13 
14 #ifndef OSGSHADOW_OCCLUDERGEOMETRY
15 #define OSGSHADOW_OCCLUDERGEOMETRY 1
16 
17 #include <osg/Drawable>
18 #include <osg/Array>
19 #include <osg/PrimitiveSet>
20 #include <osg/Polytope>
21 
22 #include <osgShadow/Export>
23 
24 
25 namespace osgShadow {
26 
27 class ShadowVolumeGeometry;
28 
35 {
36  public :
38 
40 
41  virtual Object* cloneType() const { return new OccluderGeometry(); }
42  virtual Object* clone(const osg::CopyOp& copyop) const { return new OccluderGeometry(*this,copyop); }
43  virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const OccluderGeometry*>(obj)!=NULL; }
44  virtual const char* libraryName() const { return "osgShadow"; }
45  virtual const char* className() const { return "OccluderGeometry"; }
46 
48  void computeOccluderGeometry(osg::Node* subgraph, osg::Matrix* matrix=0, float sampleRatio=1.0f);
49 
51  void computeOccluderGeometry(osg::Drawable* drawable, osg::Matrix* matrix=0, float sampleRatio=1.0f);
52 
53 
55  void computeShadowVolumeGeometry(const osg::Vec4& lightpos, ShadowVolumeGeometry& svg) const;
56 
57 
59  void setBoundingPolytope(const osg::Polytope& polytope) { _boundingPolytope = polytope; }
60 
62  osg::Polytope& getBoundingPolytope() { return _boundingPolytope; }
63 
65  const osg::Polytope& getBoundingPolytope() const { return _boundingPolytope; }
66 
67 
69  virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
70 
72  virtual osg::BoundingBox computeBoundingBox() const;
73 
74  typedef std::vector<osg::Vec3> Vec3List;
75  typedef std::vector<GLuint> UIntList;
76 
77  public:
78 
79  void processGeometry(osg::Drawable* drawable, osg::Matrix* matrix=0, float sampleRatio=1.0f);
80 
81  protected :
82 
83  virtual ~OccluderGeometry() {}
84 
85  struct Edge
86  {
87  Edge():
88  _p1(0),
89  _p2(0),
90  _t1(-1),
91  _t2(-1) {}
92 
93  Edge(unsigned int p1, unsigned int p2):
94  _p1(p1),
95  _p2(p2),
96  _t1(-1),
97  _t2(-1)
98  {
99  if (p1>p2)
100  {
101  // swap ordering so p1 is less than or equal to p2
102  _p1 = p2;
103  _p2 = p1;
104  }
105  }
106 
107  inline bool operator < (const Edge& rhs) const
108  {
109  if (_p1 < rhs._p1) return true;
110  if (_p1 > rhs._p1) return false;
111  return (_p2 < rhs._p2);
112  }
113 
114  bool addTriangle(unsigned int tri) const
115  {
116  if (_t1<0)
117  {
118  _t1 = tri;
119  return true;
120  }
121  else if (_t2<0)
122  {
123  _t2 = tri;
124  return true;
125  }
126  // argg more than two triangles assigned
127  return false;
128  }
129 
130  bool boundaryEdge() const { return _t2<0; }
131 
132  unsigned int _p1;
133  unsigned int _p2;
134 
135  mutable int _t1;
136  mutable int _t2;
137 
139  };
140 
141  typedef std::vector<Edge> EdgeList;
142 
143  inline bool isLightPointSilhouetteEdge(const osg::Vec3& lightpos, const Edge& edge) const
144  {
145  if (edge.boundaryEdge()) return true;
146 
147  float offset = 0.0f;
148 
149  osg::Vec3 delta(lightpos-_vertices[edge._p1]);
150  delta.normalize();
151 
152  float n1 = delta * _triangleNormals[edge._t1] + offset;
153  float n2 = delta * _triangleNormals[edge._t2] + offset;
154 
155  float angle_offset = 0.0f;
156 
157  n1 = cos(acosf(n1) + angle_offset);
158  n2 = cos(acosf(n2) + angle_offset);
159 
160  if (n1==0.0f && n2==0.0f) return false;
161 
162  return n1*n2 <= 0.0f;
163  }
164 
165  inline bool isLightDirectionSilhouetteEdge(const osg::Vec3& lightdirection, const Edge& edge) const
166  {
167  if (edge.boundaryEdge()) return true;
168 
169  float offset = 0.0f;
170 
171  float n1 = lightdirection * _triangleNormals[edge._t1] + offset;
172  float n2 = lightdirection * _triangleNormals[edge._t2] + offset;
173 
174  float angle_offset = 0.0f;
175 
176  n1 = cos(acosf(n1) + angle_offset);
177  n2 = cos(acosf(n2) + angle_offset);
178 
179  if (n1==0.0f && n2==0.0f) return false;
180 
181  return n1*n2 <= 0.0f;
182  }
183 
184  void setUpInternalStructures();
185 
186  void removeDuplicateVertices();
187  void removeNullTriangles();
188  void computeNormals();
189  void buildEdgeMaps();
190 
191  void computeLightDirectionSilhouetteEdges(const osg::Vec3& lightdirection, UIntList& silhouetteIndices) const;
192  void computeLightPositionSilhouetteEdges(const osg::Vec3& lightpos, UIntList& silhouetteIndices) const;
193 
195 
196  Vec3List _vertices;
197  Vec3List _normals;
200 
201  EdgeList _edges;
202 };
203 
205 {
206  public :
208 
210 
211  virtual Object* cloneType() const { return new ShadowVolumeGeometry(); }
212  virtual Object* clone(const osg::CopyOp& copyop) const { return new ShadowVolumeGeometry(*this,copyop); }
213  virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const ShadowVolumeGeometry*>(obj)!=NULL; }
214  virtual const char* libraryName() const { return "osgShadow"; }
215  virtual const char* className() const { return "ShadowVolumeGeometry"; }
216 
217  enum DrawMode
218  {
221  STENCIL_TWO_SIDED
222  };
223 
224  void setDrawMode(DrawMode mode) { _drawMode = mode; }
225  DrawMode getDrawMode() const { return _drawMode; }
226 
227  typedef std::vector<osg::Vec3> Vec3List;
228  typedef std::vector<GLuint> UIntList;
229 
230  void setVertices(const Vec3List& vertices) { _vertices = vertices; }
231  Vec3List& getVertices() { return _vertices; }
232  const Vec3List& getVertices() const { return _vertices; }
233 
234  void setNormals(const Vec3List& normals) { _normals = normals; }
235  Vec3List& getNormals() { return _normals; }
236  const Vec3List& getNormals() const { return _normals; }
237 
238 
240  virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
241 
243  virtual osg::BoundingBox computeBoundingBox() const;
244 
245  public:
246 
247  protected :
248 
250 
252  Vec3List _vertices;
253  Vec3List _normals;
254  UIntList _indices;
255 };
256 
257 }
258 
259 #endif
std::vector< osg::Vec3 > Vec3List
virtual const char * className() const
virtual Object * clone(const osg::CopyOp &copyop) const
std::vector< osg::Vec3 > Vec3List
value_type normalize()
Definition: Vec3f.h:190
#define NULL
Definition: Export.h:59
std::vector< GLuint > UIntList
Edge(unsigned int p1, unsigned int p2)
std::vector< GLuint > UIntList
virtual Object * clone(const osg::CopyOp &copyop) const
const Vec3List & getVertices() const
bool isLightDirectionSilhouetteEdge(const osg::Vec3 &lightdirection, const Edge &edge) const
bool addTriangle(unsigned int tri) const
virtual const char * className() const
osg::Polytope & getBoundingPolytope()
virtual const char * libraryName() const
#define OSGSHADOW_EXPORT
Definition: Export.h:39
bool isLightPointSilhouetteEdge(const osg::Vec3 &lightpos, const Edge &edge) const
void setBoundingPolytope(const osg::Polytope &polytope)
virtual bool isSameKindAs(const osg::Object *obj) const
void setNormals(const Vec3List &normals)
std::vector< Edge > EdgeList
virtual bool isSameKindAs(const osg::Object *obj) const
const osg::Polytope & getBoundingPolytope() const
void setVertices(const Vec3List &vertices)
Definition: Node.h:71
virtual Object * cloneType() const
virtual Object * cloneType() const
virtual const char * libraryName() const
const Vec3List & getNormals() const