source: trunk/VUT/Ogre/src/OgreItemBufferQueryManager.cpp @ 166

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