root/OpenSceneGraph/trunk/src/osg/CullStack.cpp @ 13041

Revision 13041, 8.1 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#include <osg/CullStack>
14#include <osg/Timer>
15
16#include <osg/Notify>
17#include <osg/io_utils>
18
19using namespace osg;
20
21CullStack::CullStack()
22{
23    _frustumVolume=-1.0f;
24    _bbCornerNear = 0;
25    _bbCornerFar = 7;
26    _currentReuseMatrixIndex=0;
27    _identity = new RefMatrix();
28
29    _index_modelviewCullingStack = 0;
30    _back_modelviewCullingStack = 0;
31
32    _referenceViewPoints.push_back(osg::Vec3(0.0f,0.0f,0.0f));
33}
34
35CullStack::CullStack(const CullStack& cs):
36    CullSettings(cs)
37{
38    _frustumVolume=-1.0f;
39    _bbCornerNear = 0;
40    _bbCornerFar = 7;
41    _currentReuseMatrixIndex=0;
42    _identity = new RefMatrix();
43
44    _index_modelviewCullingStack = 0;
45    _back_modelviewCullingStack = 0;
46
47    _referenceViewPoints.push_back(osg::Vec3(0.0f,0.0f,0.0f));
48}
49
50
51CullStack::~CullStack()
52{
53    reset();
54}
55
56void CullStack::reset()
57{
58
59    //
60    // first unref all referenced objects and then empty the containers.
61    //
62    _projectionStack.clear();
63    _modelviewStack.clear();
64    _viewportStack.clear();
65
66    _referenceViewPoints.clear();
67    _referenceViewPoints.push_back(osg::Vec3(0.0f,0.0f,0.0f));
68
69    _eyePointStack.clear();
70    _viewPointStack.clear();
71
72
73    _clipspaceCullingStack.clear();
74    _projectionCullingStack.clear();
75
76    //_modelviewCullingStack.clear();
77    _index_modelviewCullingStack=0;
78    _back_modelviewCullingStack = 0;
79
80    osg::Vec3 lookVector(0.0,0.0,-1.0);
81
82    _bbCornerFar = (lookVector.x()>=0?1:0) |
83                   (lookVector.y()>=0?2:0) |
84                   (lookVector.z()>=0?4:0);
85
86    _bbCornerNear = (~_bbCornerFar)&7;
87
88    _currentReuseMatrixIndex=0;
89}
90
91
92void CullStack::pushCullingSet()
93{
94    _MVPW_Stack.push_back(0L);
95
96    if (_index_modelviewCullingStack==0)
97    {
98        if (_modelviewCullingStack.empty())
99            _modelviewCullingStack.push_back(CullingSet());
100
101        _modelviewCullingStack[_index_modelviewCullingStack++].set(_projectionCullingStack.back());
102    }
103    else
104    {
105
106        const osg::Viewport& W = *_viewportStack.back();
107        const osg::Matrix& P = *_projectionStack.back();
108        const osg::Matrix& M = *_modelviewStack.back();
109
110        osg::Vec4 pixelSizeVector = CullingSet::computePixelSizeVector(W,P,M);
111
112        if (_index_modelviewCullingStack>=_modelviewCullingStack.size())
113        {
114            _modelviewCullingStack.push_back(CullingSet());
115        }
116
117        _modelviewCullingStack[_index_modelviewCullingStack++].set(_projectionCullingStack.back(),*_modelviewStack.back(),pixelSizeVector);
118
119    }
120
121    _back_modelviewCullingStack = &_modelviewCullingStack[_index_modelviewCullingStack-1];
122
123//     const osg::Polytope& polytope = _modelviewCullingStack.back()->getFrustum();
124//     const osg::Polytope::PlaneList& pl = polytope.getPlaneList();
125//     std::cout <<"new cull stack"<<std::endl;
126//     for(osg::Polytope::PlaneList::const_iterator pl_itr=pl.begin();
127//         pl_itr!=pl.end();
128//         ++pl_itr)
129//     {
130//         std::cout << "    plane "<<*pl_itr<<std::endl;
131//     }
132
133
134}
135
136void CullStack::popCullingSet()
137{
138    _MVPW_Stack.pop_back();
139
140    --_index_modelviewCullingStack;
141    if (_index_modelviewCullingStack>0) _back_modelviewCullingStack = &_modelviewCullingStack[_index_modelviewCullingStack-1];
142
143}
144
145void CullStack::pushViewport(osg::Viewport* viewport)
146{
147    _viewportStack.push_back(viewport);
148    _MVPW_Stack.push_back(0L);
149}
150
151void CullStack::popViewport()
152{
153    _viewportStack.pop_back();
154    _MVPW_Stack.pop_back();
155}
156
157void CullStack::pushProjectionMatrix(RefMatrix* matrix)
158{
159    _projectionStack.push_back(matrix);
160
161    _projectionCullingStack.push_back(osg::CullingSet());
162    osg::CullingSet& cullingSet = _projectionCullingStack.back();
163
164    // set up view frustum.
165    cullingSet.getFrustum().setToUnitFrustum(((_cullingMode&NEAR_PLANE_CULLING)!=0),((_cullingMode&FAR_PLANE_CULLING)!=0));
166    cullingSet.getFrustum().transformProvidingInverse(*matrix);
167
168    // set the culling mask ( There should be a more elegant way!)  Nikolaus H.
169    cullingSet.setCullingMask(_cullingMode);
170
171    // set the small feature culling.
172    cullingSet.setSmallFeatureCullingPixelSize(_smallFeatureCullingPixelSize);
173
174    // set up the relevant occluders which a related to this projection.
175    for(ShadowVolumeOccluderList::iterator itr=_occluderList.begin();
176        itr!=_occluderList.end();
177        ++itr)
178    {
179        //std::cout << " ** testing occluder"<<std::endl;
180        if (itr->matchProjectionMatrix(*matrix))
181        {
182            //std::cout << " ** activating occluder"<<std::endl;
183            cullingSet.addOccluder(*itr);
184        }
185    }
186
187
188
189    // need to recompute frustum volume.
190    _frustumVolume = -1.0f;
191
192    pushCullingSet();
193}
194
195void CullStack::popProjectionMatrix()
196{
197
198    _projectionStack.pop_back();
199
200    _projectionCullingStack.pop_back();
201
202    // need to recompute frustum volume.
203    _frustumVolume = -1.0f;
204
205    popCullingSet();
206}
207
208void CullStack::pushModelViewMatrix(RefMatrix* matrix, Transform::ReferenceFrame referenceFrame)
209{
210    osg::RefMatrix* originalModelView = _modelviewStack.empty() ? 0 : _modelviewStack.back().get();
211
212    _modelviewStack.push_back(matrix);
213
214    pushCullingSet();
215
216    osg::Matrix inv;
217    inv.invert(*matrix);
218
219
220    switch(referenceFrame)
221    {
222        case(Transform::RELATIVE_RF):
223            _eyePointStack.push_back(inv.getTrans());
224            _referenceViewPoints.push_back(getReferenceViewPoint());
225            _viewPointStack.push_back(getReferenceViewPoint() * inv);
226            break;
227        case(Transform::ABSOLUTE_RF):
228            _eyePointStack.push_back(inv.getTrans());
229            _referenceViewPoints.push_back(osg::Vec3(0.0,0.0,0.0));
230            _viewPointStack.push_back(_eyePointStack.back());
231            break;
232        case(Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT):
233        {
234            _eyePointStack.push_back(inv.getTrans());
235
236            osg::Vec3 referenceViewPoint = getReferenceViewPoint();
237            if (originalModelView)
238            {
239                osg::Matrix viewPointTransformMatrix;
240                viewPointTransformMatrix.invert(*originalModelView);
241                viewPointTransformMatrix.postMult(*matrix);
242                referenceViewPoint = referenceViewPoint * viewPointTransformMatrix;
243            }
244
245            _referenceViewPoints.push_back(referenceViewPoint);
246            _viewPointStack.push_back(getReferenceViewPoint() * inv);
247            break;
248        }
249    }
250
251
252    osg::Vec3 lookVector = getLookVectorLocal();
253
254    _bbCornerFar = (lookVector.x()>=0?1:0) |
255                   (lookVector.y()>=0?2:0) |
256                   (lookVector.z()>=0?4:0);
257
258    _bbCornerNear = (~_bbCornerFar)&7;
259
260}
261
262void CullStack::popModelViewMatrix()
263{
264    _modelviewStack.pop_back();
265
266    _eyePointStack.pop_back();
267    _referenceViewPoints.pop_back();
268    _viewPointStack.pop_back();
269
270    popCullingSet();
271
272
273    osg::Vec3 lookVector(0.0f,0.0f,-1.0f);
274    if (!_modelviewStack.empty())
275    {
276        lookVector = getLookVectorLocal();
277    }
278    _bbCornerFar = (lookVector.x()>=0?1:0) |
279                   (lookVector.y()>=0?2:0) |
280                   (lookVector.z()>=0?4:0);
281
282    _bbCornerNear = (~_bbCornerFar)&7;
283}
284
285void CullStack::computeFrustumVolume()
286{
287    osg::Matrix invP;
288    invP.invert(*getProjectionMatrix());
289
290    osg::Vec3 f1(-1,-1,-1); f1 = f1*invP;
291    osg::Vec3 f2(-1, 1,-1); f2 = f2*invP;
292    osg::Vec3 f3( 1, 1,-1); f3 = f3*invP;
293    osg::Vec3 f4( 1,-1,-1); f4 = f4*invP;
294
295    osg::Vec3 b1(-1,-1,1); b1 = b1*invP;
296    osg::Vec3 b2(-1, 1,1); b2 = b2*invP;
297    osg::Vec3 b3( 1, 1,1); b3 = b3*invP;
298    osg::Vec3 b4( 1,-1,1); b4 = b4*invP;
299
300    _frustumVolume = computeVolume(f1,f2,f3,b1,b2,b3)+
301                     computeVolume(f2,f3,f4,b1,b3,b4);
302
303}
Note: See TracBrowser for help on using the browser.