source: trunk/VUT/Ogre/src/OgrePlatformQueryManager.cpp @ 316

Revision 316, 7.1 KB checked in by mattausch, 19 years ago (diff)

queries are realized as templates

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