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

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

debug version: please don't check out

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