source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgrePlatformQueryManager.cpp @ 2455

Revision 2455, 6.8 KB checked in by mattausch, 17 years ago (diff)
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#include <OgreSubEntity.h>
8#include "OgrePlatformHierarchyInterface.h"
9
10
11
12namespace Ogre {
13
14
15//-----------------------------------------------------------------------
16void PlatformQueryManager::ComputeFromPointVisibility(
17                                                                                        const Vector3 &point,
18                                                                                        NodeInfoContainer *visibleNodes,
19                                                                                        MeshInfoContainer *visibleGeometry,
20                                                                                        PatchInfoContainer *visiblePatches,
21                                                                                        const bool relativeVisibility,
22                                                                                        const bool approximateVisibility)
23{
24        SceneManager *sm = static_cast<PlatformHierarchyInterface *>
25                                                                (mHierarchyInterface)->GetSceneManager();
26
27        // create a camera for the point query
28        Camera *cam = sm->createCamera("PointQueryCam");       
29
30        //save old camera
31        Camera *savedCam = mViewport->getCamera();
32       
33       
34        //////////////
35        //-- initialise new camera
36
37        mViewport->setCamera(cam);
38        cam->setPosition(point);
39
40        cam->setNearClipDistance(savedCam->getNearClipDistance());
41        cam->setFarClipDistance(savedCam->getFarClipDistance());
42
43        // set frustum to 45 degrees so all the scene can be captured with 6 shots
44        cam->setAspectRatio(1.0);
45        cam->setFOVy(Radian(Math::HALF_PI));
46
47        int sign = -1;
48       
49        ///////////////
50        //-- capture visibility from all 6 directions
51
52        for (int dir=0; dir < 6; dir++)
53        {
54                sign *= -1;
55               
56                // Print camera details
57        if (0)
58                {
59                        std::stringstream d;
60                        d << "Point query camera: " + StringConverter::toString(cam->getDerivedPosition()) +
61                                " " + "O: " + StringConverter::toString(cam->getDerivedOrientation());
62                        LogManager::getSingleton().logMessage(d.str());
63                }
64
65                // prevent from initialising geometry / node array again
66                if (dir > 0)
67                {
68                        mWasInitialised = true;
69                }
70
71                ComputeCameraVisibility(*cam,
72                                                                visibleNodes,
73                                                                visibleGeometry,
74                                                                visiblePatches,
75                                            relativeVisibility,
76                                                                approximateVisibility);
77
78                // permute directions
79                Vector3 direction(0,0,0);
80                direction[dir / 2] = sign;
81
82                cam->setDirection(direction);
83        }
84       
85        // reset camera
86        mViewport->setCamera(savedCam);
87}
88//-----------------------------------------------------------------------
89void PlatformQueryManager::ComputeCameraVisibility(
90                                                                        const Camera &camera,
91                                                                        NodeInfoContainer *visibleNodes,
92                                                                        MeshInfoContainer *visibleGeometry,
93                                                                        PatchInfoContainer *visiblePatches,
94                                                                        const bool relativeVisibility,
95                                                                        const bool approximateVisibility)
96{
97        // we need access to the scene manager and the rendersystem
98        PlatformHierarchyInterface *pfHierarchyInterface =
99                static_cast<PlatformHierarchyInterface *>(mHierarchyInterface);
100
101        SceneManager *sm = pfHierarchyInterface->GetSceneManager();
102
103
104        // const_cast allowed because camera is not changed in renderScene
105        Camera *pCam = const_cast<Camera *>(&camera);
106
107        // disable overlays, reset them later
108        bool overlayEnabled = mViewport->getOverlaysEnabled();
109        mViewport->setOverlaysEnabled(false);
110       
111        // clear background with black (i.e., not a valid item id)
112        ColourValue bg = mViewport->getBackgroundColour();
113        mViewport->setBackgroundColour(ColourValue(0, 0, 0, 0));
114        //pfHierarchyInterface->GetRenderSystem()->clearFrameBuffer(FBT_COLOUR | FBT_DEPTH);
115
116#ifdef ITEM_BUFFER
117        // initialise item buffer (if not already initialised)
118        InitItemBuffer(visibleGeometry, visiblePatches);
119
120        //////////
121        //-- render scene with item buffer (i.e., objects with their id as color codes)
122
123        // enable item buffer (must be provided by scene manager)
124        bool useItemBuffer = true;
125        sm->setOption("UseItemBuffer", &useItemBuffer);
126#endif // ITEM_BUFFER
127
128        sm->_renderScene(pCam, mViewport, false); // render item buffer
129   
130#ifdef ITEM_BUFFER
131        /////////
132        //-- collect results
133        CollectItemBufferResults(visibleGeometry, visiblePatches);
134
135        /////////
136        //-- reset state
137        useItemBuffer = false; // don't need item buffer anymore
138        sm->setOption("UseItemBuffer", &useItemBuffer);
139#endif // ITEM_BUFFER
140
141        mWasInitialised = false; // reset initialised - flag
142        mViewport->setOverlaysEnabled(overlayEnabled); // reset old overlay status
143        mViewport->setBackgroundColour(bg); // reset background color
144}
145#ifdef ITEM_BUFFER
146//-----------------------------------------------------------------------
147void PlatformQueryManager::CollectItemBufferResults(
148                                MeshInfoContainer *visibleGeometry,
149                                PatchInfoContainer *visiblePatches)
150{
151        int dimx = 0;
152        int dimy = 0;
153
154        // copy frame buffer
155        uchar *buf = mViewport->getTarget()->getBufferContents(dimx, dimy);
156
157        // loop through frame buffer and collect visible pixels
158        for (int idx = 0; idx < dimy * dimx * 3; idx += 3)
159        {
160                //-- decode color code to receive id
161                int id = buf[idx] << 16;
162                id += buf[idx + 1] << 8;
163                id += buf[idx + 2];
164
165                // if valid id <= add visibility (id values start at 1)
166                if (mQueryModes == PATCH_VISIBILITY)
167                {       
168                        if ((id > 0) && (id < (int)visiblePatches->size()))
169                        {
170                                ((*visiblePatches)[id]).AddVisibility(1, 0);
171                        }
172                }
173                else if (mQueryModes == GEOMETRY_VISIBILITY)
174                {
175                        if ((id > 0) && (id < (int)visibleGeometry->size()))
176                        {
177                                ((*visibleGeometry)[id]).AddVisibility(1, 0);
178                        }
179                }
180        }
181
182        delete [] buf;
183}
184
185//-----------------------------------------------------------------------
186void PlatformQueryManager::InitItemBuffer(
187                                MeshInfoContainer *visibleGeometry,
188                                PatchInfoContainer *visiblePatches)
189{
190        if (mWasInitialised)
191                return;
192
193        mWasInitialised = true;
194
195        SceneManager *sm =
196                //static_cast<PlatformHierarchyInterface *>(mHierarchyInterface)->GetSceneManager();
197                static_cast<PlatformHierarchyInterface *>(mHierarchyInterface)->GetSceneManager();
198
199        SceneManager::EntityIterator it = sm->getEntityIterator();
200
201        // TODO: make the function more efficient
202
203        visibleGeometry->clear();
204        visiblePatches->clear();
205
206        int id = 0;
207
208        /* We can either use patches or meshes. If patches are used, an unique id must
209           be given each patch. Otherwise the same id must be given to all patches belonging
210           to the same mesh.
211    */
212        while (it.hasMoreElements())
213        {
214                Entity *ent = it.getNext();
215
216                for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
217                {
218                        SubEntity *subEnt = ent->getSubEntity(i);
219
220                        if (mQueryModes == PATCH_VISIBILITY)
221                        {
222                                ++ id;
223                                visiblePatches->push_back(GtpVisibility::PatchInfo(subEnt, 0, 0));
224                        }
225                               
226                        subEnt->setId(id);
227                        //subEnt->setId((41 << 16) + (4 << 8) + 60);
228                }
229                       
230                if (mQueryModes == GEOMETRY_VISIBILITY)
231                {
232                        visibleGeometry->push_back(GtpVisibility::MeshInfo(ent, 0, 0));
233                        ++ id;
234                }
235        }
236}
237#endif // ITEM_BUFFER
238//-----------------------------------------------------------------------
239void PlatformQueryManager::SetViewport(Viewport *vp)
240{
241        mViewport = vp;
242}
243} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.