root/OpenSceneGraph/trunk/include/osgShadow/OccluderGeometry @ 13041

Revision 13041, 8.7 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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
25namespace osgShadow {
26
27class ShadowVolumeGeometry;
28
29/** OccluderGeometry provides a sepecialised geometry representation of objects in scene that occlude light and therefore cast shadows.
30  * OccluderGeometry supports the computation of silhouette edges and shadow volume geometries, as well as use as geometry that one can rendering
31  * into a shadow map or end caps for the ZP+ algorithm.  OccluderGeometry may be of the same resolution as an underlying geometry that it
32  * represents, or can be of lower resolution and combine manager seperate geometries together into a single shadow casting object.
33  * OccluderGeometry may be attached as UserData to Nodes or to Drawables.  */
34class OSGSHADOW_EXPORT OccluderGeometry : public osg::Drawable
35{
36    public :
37        OccluderGeometry();
38
39        OccluderGeometry(const OccluderGeometry& oc, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
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
47        /** Compute an occluder geometry containing all the geometry in specified subgraph.*/
48        void computeOccluderGeometry(osg::Node* subgraph, osg::Matrix* matrix=0, float sampleRatio=1.0f);
49
50        /** Compute an occluder geometry containing the geometry in specified drawable.*/
51        void computeOccluderGeometry(osg::Drawable* drawable, osg::Matrix* matrix=0, float sampleRatio=1.0f);
52
53
54        /** Compute ShadowVolumeGeometry. */
55        void computeShadowVolumeGeometry(const osg::Vec4& lightpos, ShadowVolumeGeometry& svg) const;
56
57
58        /** Set the bounding polytope of the OccluderGeometry.*/
59        void setBoundingPolytope(const osg::Polytope& polytope) { _boundingPolytope = polytope; }
60
61        /** Get the bounding polytope of the OccluderGeometry.*/
62        osg::Polytope& getBoundingPolytope() { return _boundingPolytope; }
63
64        /** Get the const bounding polytope of the OccluderGeometry.*/
65        const osg::Polytope& getBoundingPolytope() const { return _boundingPolytope; }
66
67
68        /** Render the occluder geometry. */
69        virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
70
71        /** Compute the bounding box around occluder geometry.*/
72        virtual osg::BoundingBox computeBound() 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
138            mutable osg::Vec3   _normal;
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
194        osg::Polytope _boundingPolytope;
195
196        Vec3List _vertices;
197        Vec3List _normals;
198        Vec3List _triangleNormals;
199        UIntList _triangleIndices;
200
201        EdgeList _edges;
202};
203
204class OSGSHADOW_EXPORT ShadowVolumeGeometry : public osg::Drawable
205{
206    public :
207        ShadowVolumeGeometry();
208
209        ShadowVolumeGeometry(const ShadowVolumeGeometry& oc, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
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        {
219            GEOMETRY,
220            STENCIL_TWO_PASS,
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
239        /** Render the occluder geometry. */
240        virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
241
242        /** Compute the bounding box around occluder geometry.*/
243        virtual osg::BoundingBox computeBound() const;
244
245    public:
246
247    protected :
248
249        virtual ~ShadowVolumeGeometry() {}
250
251        DrawMode _drawMode;
252        Vec3List _vertices;
253        Vec3List _normals;
254        UIntList _indices;
255};
256
257}
258
259#endif
Note: See TracBrowser for help on using the browser.