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

Revision 2280, 7.8 KB checked in by mattausch, 17 years ago (diff)

removed dependency on ogre in gtpvisibility

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