source: OGRE/trunk/src/OgreItemBufferQueryManager.cpp @ 171

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

fixed visibilityQueries

Line 
1#include "OgreItemBufferQueryManager.h"
2#include <OgreLogManager.h>
3#include <OgreStringConverter.h>
4#include <vector>
5#include <OgreSubEntity.h>
6
7namespace Ogre {
8
9//-----------------------------------------------------------------------
10ItemBufferQueryManager::ItemBufferQueryManager(PlatformHierarchyInterface *hierarchyInterface,
11                                                                                           Viewport *vp,
12                                                                                           const bool renderPatches):
13PlatformQueryManager(hierarchyInterface, vp), mRenderPatchesForItemBuffer(renderPatches)
14{
15}
16//-----------------------------------------------------------------------
17void ItemBufferQueryManager::ComputeCameraVisibility(const Camera &camera,
18                            InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
19                            InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
20                                InfoContainer<GtpVisibility::PatchInfo> *visiblePatches,
21                            bool relativeVisibility)
22{
23        // we need access to the scene manager and the rendersystem
24        PlatformHierarchyInterface *pfHierarchyInterface =
25                dynamic_cast<PlatformHierarchyInterface *>(mHierarchyInterface);
26
27        SceneManager *sm = pfHierarchyInterface->GetSceneManager();
28
29
30        // const_cast allowed because camera is not changed in renderScene
31        Camera *pCam = const_cast<Camera *>(&camera);
32
33        // disable overlays, reset them later
34        bool overlayEnabled = mViewport->getOverlaysEnabled();
35        mViewport->setOverlaysEnabled(false);
36       
37        // clear background with black (i.e., not a valid item id)
38        ColourValue bg = mViewport->getBackgroundColour();
39        mViewport->setBackgroundColour(ColourValue(0, 0, 0, 0));
40        //pfHierarchyInterface->GetRenderSystem()->clearFrameBuffer(FBT_COLOUR | FBT_DEPTH);
41
42
43        //-- render scene with item buffer (i.e., objects with their id as color codes)
44
45        // enable item buffer (must be provided by scene manager)
46        bool useItemBuffer = true;
47        sm->setOption("UseItemBuffer", &useItemBuffer);
48        sm->_renderScene(pCam, mViewport, false); // render item buffer
49   
50
51        //-- collect results
52       
53        // initialise item buffer (if not already initialised)
54        InitItemBuffer(visibleNodes, visibleGeometry, visiblePatches);
55
56        int dimx = 0;
57        int dimy = 0;
58
59        // copy frame buffer
60        uchar *buf = mViewport->getTarget()->getBufferContents(dimx, dimy);
61
62        int n = mRenderPatchesForItemBuffer ?
63                (int)visiblePatches->size() : (int)visibleGeometry->size();
64
65        //std::stringstream d; d << "dimx: " << dimx << ", dimy: " << dimy; LogManager::getSingleton().logMessage(d.str());
66
67        // loop through frame buffer and collect visible pixels
68        for (int idx = 0; idx < dimy * dimx * 3; idx += 3)
69        {
70                //-- decode color code to receive id
71                int id = buf[idx] << 16;
72                id += buf[idx + 1] << 8;
73                id += buf[idx + 2];
74
75                //std::stringstream d; d << "myid: " << (int)buf[idx] << " " << (int)buf[idx + 1] << " " << (int)buf[idx + 2]; LogManager::getSingleton().logMessage(d.str());
76
77                // if valid id <= add visibility (id values start at 1)
78                if ((id > 0) && (id < n))
79                {
80                        if (mRenderPatchesForItemBuffer)
81                        {
82                                ((*visiblePatches)[id]).AddVisibility(1, 1);
83                        }
84                        else
85                        {
86                                ((*visibleGeometry)[id]).AddVisibility(1, 1);
87                        }
88                }
89        }
90
91
92        //-- reset options
93
94        useItemBuffer = false; // don't need item buffer anymore
95        sm->setOption("UseItemBuffer", &useItemBuffer);
96
97        mWasInitialised = false; // reset initialised - flag
98        mViewport->setOverlaysEnabled(overlayEnabled); // reset old overlay status
99        mViewport->setBackgroundColour(bg); // reset background color
100
101        delete [] buf;  // delete copy of the frame buffer
102}
103//-----------------------------------------------------------------------
104void ItemBufferQueryManager::InitItemBuffer(
105                                InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
106                            InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
107                                InfoContainer<GtpVisibility::PatchInfo> *visiblePatches)
108{
109        if (mWasInitialised)
110                return;
111
112        mWasInitialised = true;
113
114        SceneManager *sm =
115                dynamic_cast<PlatformHierarchyInterface *>(mHierarchyInterface)->GetSceneManager();
116
117        SceneManager::EntityIterator it = sm->getEntityIterator();
118
119        // TODO: make this more efficient
120        visibleGeometry->clear();
121        visibleNodes->clear();
122        visiblePatches->clear();
123
124        int id = 0;
125
126        /* We can either use patches or meshes. If patches are used, an unique id must
127           be given each patch. Otherwise the same id must be given to all patches belonging
128           to the same mesh.
129    */
130        while (it.hasMoreElements())
131        {
132                Entity *ent = it.getNext();
133
134                for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
135                {
136                        SubEntity *subEnt = ent->getSubEntity(i);
137
138                        if (mRenderPatchesForItemBuffer)
139                        {
140                                ++ id;
141                                visiblePatches->push_back(GtpVisibility::PatchInfo(subEnt, 0, 0));
142                        }
143                               
144                        subEnt->setId(id);
145                        //subEnt->setId((41 << 16) + (4 << 8) + 60);
146                        //subEnt->setId((2 << 16) + (4 << 8) + 60);
147                }
148                       
149                if (!mRenderPatchesForItemBuffer)
150                {
151                        visibleGeometry->push_back(GtpVisibility::MeshInfo(ent, 0, 0));
152                        ++ id;
153                }
154        }
155}
156
157/*
158//-----------------------------------------------------------------------
159Entity* VisibilityOctreeSceneManager::createEntity(const String& entityName,
160                                                                                                        const String& meshName)
161{
162        Entity *ent = SceneManager::createEntity(entityName, meshName);
163
164        for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
165        {
166                ent->getSubEntity(i)->setId(mCurrentEntityId);
167        }
168
169        // increase counter of entity id values
170        ++ mCurrentEntityId;
171
172        return ent;
173}
174*/
175} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.