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

Revision 2171, 7.7 KB checked in by mattausch, 17 years ago (diff)

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