source: trunk/VUT/Ogre/src/OgrePlatformQueryManager.cpp @ 143

Revision 143, 9.2 KB checked in by mattausch, 19 years ago (diff)

updated visibility queries

Line 
1#include "OgrePlatformQueryManager.h"
2#include "OcclusionQuery.h"
3#include <OgreSceneManager.h>
4#include <OgreLogManager.h>
5#include <OgreStringConverter.h>
6#include <vector>
7
8
9namespace Ogre {
10//-----------------------------------------------------------------------
11PlatformQueryManager::PlatformQueryManager(PlatformHierarchyInterface *hierarchyInterface, Viewport *vp):
12QueryManager(hierarchyInterface), mViewport(vp)
13{
14}
15//-----------------------------------------------------------------------
16bool PlatformQueryManager::ShootRay(const Ray &ray, std::vector<Mesh *> *visibleMeshes, bool isGlobalLine)
17{
18    // run OGRE ray shooting query
19    return false;
20}
21//-----------------------------------------------------------------------
22void PlatformQueryManager::ComputeCameraVisibility(const Camera &camera,
23                            InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
24                            InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
25                            bool projectedPixels)
26{
27        // we need access to the scene manager and the rendersystem
28        PlatformHierarchyInterface *pfHierarchyInterface =
29                dynamic_cast<PlatformHierarchyInterface *>(mHierarchyInterface);
30
31        //-- Render scene to get conservative visibility and fill depth buffer
32
33        // can do const_cast because Camera no changed in renderScene
34        Camera *pCam = const_cast<Camera *>(&camera);
35
36        bool overlayEnabled = mViewport->getOverlaysEnabled();
37        mViewport->setOverlaysEnabled(false);
38        pfHierarchyInterface->GetSceneManager()->_renderScene(pCam, mViewport, false);
39
40        /*
41                Two query lists:
42                We test two to get exact visibility with regard to the current camera and
43                issue all queries at once to avoid starvation & stalls.
44        */
45        GtpVisibility::QueryList queryList[2];
46       
47        // get rendered hierarchy nodes
48        GtpVisibility::HierarchyNodeList *nodeList = mHierarchyInterface->GetRenderedNodes();
49        // vector for storing entities of meshes
50        GtpVisibility::GeometryList geometryList;
51       
52        GtpVisibility::HierarchyNodeList::iterator nodeIt, nodeIt_end = nodeList->end();
53        // geometry list has still do be built
54        GtpVisibility::GeometryList::iterator geometryIt, geometryIt_end;
55
56        // to obtain the correct number of projected pixels, depth write must be disabled
57        bool enableDepthWrite = false;
58
59        // this option must be provided by the scene manager
60        pfHierarchyInterface->GetSceneManager()->setOption("DepthWrite", &enableDepthWrite);
61
62        /* relative visiblity:
63                1) get visible pixels count of objects
64                2) clear frame buffer
65                3) get projected visible pixels count:
66                   test all objects again without depth write (set as option in scene manager)
67                4) calculate ratio between visible vs. projected pixels
68        */
69        // for relative visibility we need 2 rendering passes
70        int n = projectedPixels ? 2 : 1;
71       
72        for (int i=0; i<n; ++i)
73        {
74                //-- queries for hierarchy nodes
75                for (nodeIt = nodeList->begin(); nodeIt != nodeIt_end; ++nodeIt)               
76                {
77                        // TODO: DELETE QUERIES FROM PREVIOUS RENDER
78                        queryList[i].push_back(mHierarchyInterface->IssueOcclusionQuery(*nodeIt, false));
79                       
80                        // store geometry of the hierarchy node in a geometry list (only once!)
81                        if (i == 0)
82                        {
83                                mHierarchyInterface->GetGeometry(*nodeIt, &geometryList, false);
84                        }
85                }
86
87                geometryIt_end = geometryList.end();
88
89                //-- add queries for geometry
90                for (geometryIt = geometryList.begin(); geometryIt != geometryIt_end; ++geometryIt)
91                {
92                        queryList[i].push_back(mHierarchyInterface->IssueOcclusionQuery(*geometryIt));
93                }
94
95       
96                pfHierarchyInterface->GetRenderSystem()->clearFrameBuffer(FBT_DEPTH);
97        }
98
99        enableDepthWrite = true;
100        // this option must be provided by the scene manager
101        pfHierarchyInterface->GetSceneManager()->setOption("DepthWrite", &enableDepthWrite);
102       
103        mViewport->setOverlaysEnabled(overlayEnabled);
104
105        //---- collect results
106        unsigned int visiblePixels = 0;
107        std::pair<InfoContainer<GtpVisibility::NodeInfo>::iterator, bool> insertNode;
108        std::pair<InfoContainer<GtpVisibility::MeshInfo>::iterator, bool> insertGeom;
109
110        GtpVisibility::QueryList::iterator visQueryIt, projQueryIt;
111
112        visQueryIt = queryList[0].begin();
113        projQueryIt = queryList[1].begin();
114
115       
116        for (nodeIt = nodeList->begin(); nodeIt != nodeIt_end; ++nodeIt)
117        {
118                (*visQueryIt)->GetQueryResult(visiblePixels, true);
119       
120                int visiblePixels = visiblePixels;
121                int projectedPixels = 0;
122
123                if (projectedPixels)
124                {
125                        (*projQueryIt)->GetQueryResult(visiblePixels, true);
126       
127                        mProjectedPixels = visiblePixels;
128               
129                        ++projQueryIt;
130                }
131
132                ++visQueryIt;
133               
134                // nodes with visibilty 0 in queue:
135                // happens if node is intersected by near plane
136                if (visiblePixels > 0)
137                {
138                        visibleNodes->push_back(GtpVisibility::NodeInfo(*nodeIt, visiblePixels, projectedPixels));
139                }
140        }
141
142        //---- queries for geometry
143        geometryIt_end = geometryList.end();
144       
145        for (geometryIt = geometryList.begin(); geometryIt != geometryIt_end; ++geometryIt)
146        {
147                (*visQueryIt)->GetQueryResult(visiblePixels, true);
148               
149                int visiblePixels = visiblePixels;
150                int projectedPixels = 0;
151
152                if (projectedPixels)
153                {
154                        (*projQueryIt)->GetQueryResult(visiblePixels, true);
155
156                        mProjectedPixels = visiblePixels;
157
158                        ++projQueryIt;
159                }
160
161                ++visQueryIt;
162
163                // approximate depth ordering during rendering =>
164                // geometry maybe occluded
165                if (isVisible)
166                {                       
167                        visibleGeometry->push_back(GtpVisibility::MeshInfo(*geometryIt,visiblePixels, projectedPixels));
168                }
169        }
170
171}
172//-----------------------------------------------------------------------
173inline bool nodeinfo_eq(const GtpVisibility::NodeInfo &info1, const GtpVisibility::NodeInfo &info2)
174{
175        return info1.GetNode() == info2.GetNode();
176}
177//-----------------------------------------------------------------------
178inline bool meshinfo_eq(const GtpVisibility::MeshInfo &info1, const GtpVisibility::MeshInfo &info2)
179{
180        return info1.GetMesh() == info2.GetMesh();
181}
182//-----------------------------------------------------------------------
183void PlatformQueryManager::ComputeFromPointVisibility(const Vector3 &point,
184                               InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
185                               InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
186                               bool projectedPixels)
187{
188        SceneManager *sm = dynamic_cast<PlatformHierarchyInterface *>(mHierarchyInterface)->GetSceneManager();
189        Camera *cam = sm->createCamera("PointQueryCam");       
190
191        //save old camera
192        Camera *savedCam = mViewport->getCamera();
193       
194        // --- initialise new camera
195        mViewport->setCamera(cam);
196        cam->setPosition(point);
197
198        cam->setNearClipDistance(savedCam->getNearClipDistance());
199        cam->setFarClipDistance(savedCam->getFarClipDistance());
200
201        // set frustum to 45 degrees so all the scene can be captured with 6 shots
202        cam->setAspectRatio(1.0);
203        cam->setFOVy(Radian(Math::HALF_PI));
204
205        std::stringstream d;
206        d << "old camera: " + StringConverter::toString(savedCam->getDerivedPosition()) +
207                " " + "O: " + StringConverter::toString(savedCam->getDerivedOrientation());
208        LogManager::getSingleton().logMessage(d.str());
209
210        int sign = -1;
211       
212        // ---- capture visibility from all 6 directions
213        for (int i=0; i < 6; i++)       
214        {
215                sign *= -1;
216               
217                // Print camera details
218        std::stringstream d;
219                d << "Point query camera: " + StringConverter::toString(cam->getDerivedPosition()) +
220                        " " + "O: " + StringConverter::toString(cam->getDerivedOrientation());
221                LogManager::getSingleton().logMessage(d.str());
222
223                ComputeCameraVisibility(*cam, visibleNodes, visibleGeometry, projectedPixels);
224               
225                //mViewport->getTarget()->update(); for(int j=0; j<10000000; j++)       printf("HAAHHAHAHAHAH");
226
227                // permute directions
228                Vector3 dir(0,0,0);
229                dir[i/2] = sign;
230
231                cam->setDirection(dir);
232        }
233       
234        // reset camera
235        mViewport->setCamera(savedCam);
236
237        // --- single out duplicates
238
239        // before duplicates can be deleted we have to add up visibility
240
241        // --- visible nodes
242        sort(visibleNodes->begin(), visibleNodes->end());
243        InfoContainer<GtpVisibility::NodeInfo>::iterator visibleNodesIt,
244                visibleNodesIt_end = visibleNodes->end();
245       
246        GtpVisibility::NodeInfo *nodeInfo = NULL;
247
248        for (visibleNodesIt = visibleNodes->begin(); visibleNodesIt != visibleNodesIt_end;
249                ++visibleNodesIt);
250        {
251                if (!nodeInfo || (nodeInfo->GetNode() != (*visibleNodesIt).GetNode()))
252                {
253                        nodeInfo = &(*visibleNodesIt);
254                }
255                else
256                {
257                        // add visibility
258                        nodeInfo->SetVisibility(nodeInfo->GetVisiblePixels() +
259                                (*visibleNodesIt).GetVisiblePixels());
260                }
261
262        }
263       
264        // now delete duplicates
265        visibleNodes->erase( std::unique(visibleNodes->begin(),
266                visibleNodes->end(), nodeinfo_eq), visibleNodes->end());
267
268        // --- visible geometry
269        sort(visibleGeometry->begin(), visibleGeometry->end());
270        InfoContainer<GtpVisibility::MeshInfo>::iterator visibleGeomIt,
271                visibleGeomIt_end = visibleGeometry->end();
272
273        GtpVisibility::MeshInfo *geomInfo = NULL;
274
275        for (visibleGeomIt = visibleGeometry->begin(); visibleGeomIt != visibleGeomIt_end;
276                ++visibleGeomIt);
277        {
278                if (!geomInfo || (geomInfo->GetMesh() != (*visibleGeomIt).GetMesh()))
279                {
280                        geomInfo = &(*visibleGeomIt);
281                }
282                else // info points to equal mesh
283                {
284                        // add visibility
285                        geomInfo->SetVisibility(geomInfo->GetVisiblePixels() +
286                                (*visibleGeomIt).GetVisiblePixels());
287                }
288        }
289
290        // now delete duplicates
291        visibleGeometry->erase(std::unique(visibleGeometry->begin(),
292                visibleGeometry->end(), meshinfo_eq), visibleGeometry->end());
293       
294}
295//-----------------------------------------------------------------------
296void PlatformQueryManager::SetViewport(Viewport *vp)
297{
298        mViewport = vp;
299}
300} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.