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

Revision 171, 6.9 KB checked in by mattausch, 19 years ago (diff)

fixed visibilityQueries

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, bool renderPatches):
15QueryManager(hierarchyInterface),
16mViewport(vp),
17mWasInitialised(false),
18mRenderPatches(false)
19{
20}
21//-----------------------------------------------------------------------
22bool PlatformQueryManager::ShootRay(const Ray &ray, std::vector<Mesh *> *visibleMeshes, bool isGlobalLine)
23{
24    // run OGRE ray shooting query
25    return false;
26}
27//-----------------------------------------------------------------------
28void PlatformQueryManager::ComputeFromPointVisibility(const Vector3 &point,
29                               InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
30                               InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
31                                   InfoContainer<GtpVisibility::PatchInfo> *visiblePatches,
32                               bool relativeVisibility)
33{
34        SceneManager *sm = dynamic_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                            InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
90                            InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
91                                InfoContainer<GtpVisibility::PatchInfo> *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
98        SceneManager *sm = pfHierarchyInterface->GetSceneManager();
99
100
101        // const_cast allowed because camera is not changed in renderScene
102        Camera *pCam = const_cast<Camera *>(&camera);
103
104        // disable overlays, reset them later
105        bool overlayEnabled = mViewport->getOverlaysEnabled();
106        mViewport->setOverlaysEnabled(false);
107       
108        // clear background with black (i.e., not a valid item id)
109        ColourValue bg = mViewport->getBackgroundColour();
110        mViewport->setBackgroundColour(ColourValue(0, 0, 0, 0));
111        //pfHierarchyInterface->GetRenderSystem()->clearFrameBuffer(FBT_COLOUR | FBT_DEPTH);
112
113        // initialise item buffer (if not already initialised)
114        InitItemBuffer(visibleGeometry, visiblePatches);
115
116        //-- render scene with item buffer (i.e., objects with their id as color codes)
117
118        // enable item buffer (must be provided by scene manager)
119        bool useItemBuffer = true;
120        sm->setOption("UseItemBuffer", &useItemBuffer);
121
122
123        sm->_renderScene(pCam, mViewport, false); // render item buffer
124   
125
126        //-- collect results
127
128        int dimx = 0;
129        int dimy = 0;
130
131        // copy frame buffer
132        uchar *buf = mViewport->getTarget()->getBufferContents(dimx, dimy);
133
134        int n = mRenderPatches ?
135                (int)visiblePatches->size() : (int)visibleGeometry->size();
136
137        //std::stringstream d; d << "dimx: " << dimx << ", dimy: " << dimy; LogManager::getSingleton().logMessage(d.str());
138
139        // loop through frame buffer and collect visible pixels
140        for (int idx = 0; idx < dimy * dimx * 3; idx += 3)
141        {
142                //-- decode color code to receive id
143                int id = buf[idx] << 16;
144                id += buf[idx + 1] << 8;
145                id += buf[idx + 2];
146
147                //std::stringstream d; d << "myid: " << (int)buf[idx] << " " << (int)buf[idx + 1] << " " << (int)buf[idx + 2]; LogManager::getSingleton().logMessage(d.str());
148
149                // if valid id <= add visibility (id values start at 1)
150                if ((id > 0) && (id < n))
151                {
152                        if (mRenderPatches)
153                        {
154                                ((*visiblePatches)[id]).AddVisibility(1, 0);
155                        }
156                        else
157                        {
158                                ((*visibleGeometry)[id]).AddVisibility(1, 0);
159                        }
160                }
161        }
162
163
164        //-- reset options
165
166        useItemBuffer = false; // don't need item buffer anymore
167        sm->setOption("UseItemBuffer", &useItemBuffer);
168
169        mWasInitialised = false; // reset initialised - flag
170        mViewport->setOverlaysEnabled(overlayEnabled); // reset old overlay status
171        mViewport->setBackgroundColour(bg); // reset background color
172
173        delete [] buf;  // delete copy of the frame buffer
174}
175//-----------------------------------------------------------------------
176void PlatformQueryManager::InitItemBuffer(
177                                InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
178                                InfoContainer<GtpVisibility::PatchInfo> *visiblePatches)
179{
180        if (mWasInitialised)
181                return;
182
183        mWasInitialised = true;
184
185        SceneManager *sm =
186                dynamic_cast<PlatformHierarchyInterface *>(mHierarchyInterface)->GetSceneManager();
187
188        SceneManager::EntityIterator it = sm->getEntityIterator();
189
190        // TODO: make the function more efficient
191
192        visibleGeometry->clear();
193        visiblePatches->clear();
194
195        int id = 0;
196
197        /* We can either use patches or meshes. If patches are used, an unique id must
198           be given each patch. Otherwise the same id must be given to all patches belonging
199           to the same mesh.
200    */
201        while (it.hasMoreElements())
202        {
203                Entity *ent = it.getNext();
204
205                for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
206                {
207                        SubEntity *subEnt = ent->getSubEntity(i);
208
209                        if (mRenderPatches)
210                        {
211                                ++ id;
212                                visiblePatches->push_back(GtpVisibility::PatchInfo(subEnt, 0, 0));
213                        }
214                               
215                        subEnt->setId(id);
216                        //subEnt->setId((41 << 16) + (4 << 8) + 60);
217                        //subEnt->setId((2 << 16) + (4 << 8) + 60);
218                }
219                       
220                if (!mRenderPatches)
221                {
222                        visibleGeometry->push_back(GtpVisibility::MeshInfo(ent, 0, 0));
223                        ++ id;
224                }
225        }
226}
227//-----------------------------------------------------------------------
228void PlatformQueryManager::SetViewport(Viewport *vp)
229{
230        mViewport = vp;
231}
232} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.