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

Revision 726, 7.3 KB checked in by mattausch, 18 years ago (diff)

improved performance of TerrainSceneManager?
revisit octreescenemanager

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