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

Revision 2255, 7.9 KB checked in by mattausch, 17 years ago (diff)

improved scenemanager config

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