root/OpenSceneGraph/trunk/include/osg/CullStack @ 13041

Revision 13041, 9.7 kB (checked in by robert, 2 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 OSG_CULLSTACK
15#define OSG_CULLSTACK 1
16
17#include <osg/CullingSet>
18#include <osg/CullSettings>
19#include <osg/Viewport>
20#include <osg/fast_back_stack>
21#include <osg/Transform>
22
23namespace osg {
24
25/** A CullStack class which accumulates the current project, modelview matrices
26and the CullingSet. */
27class OSG_EXPORT CullStack : public osg::CullSettings
28{
29
30    public:
31
32
33        CullStack();
34        CullStack(const CullStack& cs);
35
36        ~CullStack();
37
38        typedef std::vector<ShadowVolumeOccluder>   OccluderList;
39
40        void reset();
41
42        void pushCullingSet();
43        void popCullingSet();
44
45        void setOccluderList(const ShadowVolumeOccluderList& svol) { _occluderList = svol; }
46        ShadowVolumeOccluderList& getOccluderList() { return _occluderList; }
47        const ShadowVolumeOccluderList& getOccluderList() const { return _occluderList; }
48
49        void pushViewport(osg::Viewport* viewport);
50        void popViewport();
51
52        void pushProjectionMatrix(osg::RefMatrix* matrix);
53        void popProjectionMatrix();
54
55        void pushModelViewMatrix(osg::RefMatrix* matrix, Transform::ReferenceFrame referenceFrame);
56        void popModelViewMatrix();
57
58        inline float getFrustumVolume() { if (_frustumVolume<0.0f) computeFrustumVolume(); return _frustumVolume; }
59
60
61        /** Compute the pixel size of an object at position v, with specified radius.*/
62        float pixelSize(const Vec3& v,float radius) const
63        {
64            return getCurrentCullingSet().pixelSize(v,radius);
65        }
66
67        /** Compute the pixel size of the bounding sphere.*/
68        float pixelSize(const BoundingSphere& bs) const
69        {
70            return pixelSize(bs.center(),bs.radius());
71        }
72
73        /** Compute the pixel size of an object at position v, with specified radius. fabs()ed to always be positive. */
74        float clampedPixelSize(const Vec3& v,float radius) const
75        {
76            return getCurrentCullingSet().clampedPixelSize(v,radius);
77        }
78
79        /** Compute the pixel size of the bounding sphere. fabs()ed to always be positive. */
80        float clampedPixelSize(const BoundingSphere& bs) const
81        {
82            return clampedPixelSize(bs.center(),bs.radius());
83        }
84
85        inline void disableAndPushOccludersCurrentMask(NodePath& nodePath)
86        {
87            getCurrentCullingSet().disableAndPushOccludersCurrentMask(nodePath);
88        }
89
90        inline void popOccludersCurrentMask(NodePath& nodePath)
91        {
92            getCurrentCullingSet().popOccludersCurrentMask(nodePath);
93        }
94
95        inline bool isCulled(const std::vector<Vec3>& vertices)
96        {
97            return getCurrentCullingSet().isCulled(vertices);
98        }
99
100        inline bool isCulled(const BoundingBox& bb)
101        {
102            return bb.valid() && getCurrentCullingSet().isCulled(bb);
103        }
104
105        inline bool isCulled(const BoundingSphere& bs)
106        {
107            return getCurrentCullingSet().isCulled(bs);
108        }
109
110        inline bool isCulled(const osg::Node& node)
111        {
112            return node.isCullingActive() && getCurrentCullingSet().isCulled(node.getBound());
113        }
114
115        inline void pushCurrentMask()
116        {
117            getCurrentCullingSet().pushCurrentMask();
118        }
119
120        inline void popCurrentMask()
121        {
122            getCurrentCullingSet().popCurrentMask();
123        }
124
125
126        typedef std::vector< CullingSet > CullingStack;
127
128        inline CullingStack& getClipSpaceCullingStack() { return _clipspaceCullingStack; }
129
130        inline CullingStack& getProjectionCullingStack() { return _projectionCullingStack; }
131
132        inline CullingStack& getModelViewCullingStack() { return _modelviewCullingStack; }
133
134        inline CullingSet& getCurrentCullingSet() { return *_back_modelviewCullingStack; }
135        inline const CullingSet& getCurrentCullingSet() const { return *_back_modelviewCullingStack; }
136
137        inline osg::Viewport* getViewport();
138        inline osg::RefMatrix* getModelViewMatrix();
139        inline osg::RefMatrix* getProjectionMatrix();
140        inline osg::Matrix getWindowMatrix();
141        inline const osg::RefMatrix* getMVPW();
142
143        inline const osg::Vec3& getReferenceViewPoint() const { return _referenceViewPoints.back(); }
144        inline void pushReferenceViewPoint(const osg::Vec3& viewPoint) { _referenceViewPoints.push_back(viewPoint); }
145        inline void popReferenceViewPoint() { _referenceViewPoints.pop_back(); }
146
147        inline const osg::Vec3& getEyeLocal() const { return _eyePointStack.back(); }
148
149        inline const osg::Vec3& getViewPointLocal() const { return _viewPointStack.back(); }
150
151        inline const osg::Vec3 getUpLocal() const
152        {
153            const osg::Matrix& matrix = *_modelviewStack.back();
154            return osg::Vec3(matrix(0,1),matrix(1,1),matrix(2,1));
155        }
156
157        inline const osg::Vec3 getLookVectorLocal() const
158        {
159            const osg::Matrix& matrix = *_modelviewStack.back();
160            return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2));
161        }
162
163
164    protected:
165
166        // base set of shadow volume occluder to use in culling.
167        ShadowVolumeOccluderList                                    _occluderList;
168
169        typedef fast_back_stack< ref_ptr<RefMatrix> >                  MatrixStack;
170
171        MatrixStack                                                 _projectionStack;
172
173        MatrixStack                                                 _modelviewStack;
174        MatrixStack                                                 _MVPW_Stack;
175
176        typedef fast_back_stack<ref_ptr<Viewport> >                 ViewportStack;
177        ViewportStack                                               _viewportStack;
178
179        typedef fast_back_stack<Vec3>                               EyePointStack;
180        EyePointStack                                               _referenceViewPoints;
181        EyePointStack                                               _eyePointStack;
182        EyePointStack                                               _viewPointStack;
183
184        CullingStack                                                _clipspaceCullingStack;
185        CullingStack                                                _projectionCullingStack;
186
187        CullingStack                                                _modelviewCullingStack;
188        unsigned int                                                _index_modelviewCullingStack;
189        CullingSet*                                                 _back_modelviewCullingStack;
190
191        void computeFrustumVolume();
192        float                                                       _frustumVolume;
193
194        unsigned int                                                _bbCornerNear;
195        unsigned int                                                _bbCornerFar;
196
197        ref_ptr<osg::RefMatrix>                                     _identity;
198
199        typedef std::vector< osg::ref_ptr<osg::RefMatrix> > MatrixList;
200        MatrixList _reuseMatrixList;
201        unsigned int _currentReuseMatrixIndex;
202
203        inline osg::RefMatrix* createOrReuseMatrix(const osg::Matrix& value);
204
205
206};
207
208inline osg::Viewport* CullStack::getViewport()
209{
210    if (!_viewportStack.empty())
211    {
212        return _viewportStack.back().get();
213    }
214    else
215    {
216        return 0L;
217    }
218}
219
220inline osg::RefMatrix* CullStack::getModelViewMatrix()
221{
222    if (!_modelviewStack.empty())
223    {
224        return _modelviewStack.back().get();
225    }
226    else
227    {
228        return _identity.get();
229    }
230}
231
232inline osg::RefMatrix* CullStack::getProjectionMatrix()
233{
234    if (!_projectionStack.empty())
235    {
236        return _projectionStack.back().get();
237    }
238    else
239    {
240        return _identity.get();
241    }
242}
243
244inline osg::Matrix CullStack::getWindowMatrix()
245{
246    if (!_viewportStack.empty())
247    {
248        osg::Viewport* viewport = _viewportStack.back().get();
249        return viewport->computeWindowMatrix();
250    }
251    else
252    {
253        return *_identity;
254    }
255}
256
257inline const osg::RefMatrix* CullStack::getMVPW()
258{
259    if (!_MVPW_Stack.empty())
260    {
261        if (!_MVPW_Stack.back())
262        {
263            _MVPW_Stack.back() = createOrReuseMatrix(*getModelViewMatrix());
264            (*_MVPW_Stack.back()) *= *(getProjectionMatrix());
265            (*_MVPW_Stack.back()) *= getWindowMatrix();
266        }
267        return _MVPW_Stack.back().get();
268    }
269    else
270    {
271        return _identity.get();
272    }
273}
274
275inline RefMatrix* CullStack::createOrReuseMatrix(const osg::Matrix& value)
276{
277    // skip of any already reused matrix.
278    while (_currentReuseMatrixIndex<_reuseMatrixList.size() &&
279           _reuseMatrixList[_currentReuseMatrixIndex]->referenceCount()>1)
280    {
281        ++_currentReuseMatrixIndex;
282    }
283
284    // if still within list, element must be singularly referenced
285    // there return it to be reused.
286    if (_currentReuseMatrixIndex<_reuseMatrixList.size())
287    {
288        RefMatrix* matrix = _reuseMatrixList[_currentReuseMatrixIndex++].get();
289        matrix->set(value);
290        return matrix;
291    }
292
293    // otherwise need to create new matrix.
294    osg::RefMatrix* matrix = new RefMatrix(value);
295    _reuseMatrixList.push_back(matrix);
296    ++_currentReuseMatrixIndex;
297    return matrix;
298}
299
300}    // end of namespace
301
302#endif
Note: See TracBrowser for help on using the browser.