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

Revision 156, 4.7 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
6
7namespace Ogre {
8//-----------------------------------------------------------------------
9ItemBufferQueryManager::ItemBufferQueryManager(PlatformHierarchyInterface *hierarchyInterface, Viewport *vp):
10PlatformQueryManager(hierarchyInterface, vp)
11{
12}
13//-----------------------------------------------------------------------
14bool ItemBufferQueryManager::ShootRay(const Ray &ray, std::vector<Mesh *> *visibleMeshes, bool isGlobalLine)
15{
16    // run OGRE ray shooting query
17    return false;
18}
19//-----------------------------------------------------------------------
20void ItemBufferQueryManager::ComputeCameraVisibility(const Camera &camera,
21                            InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
22                            InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
23                            bool relativeVisibility)
24{
25        // initialise item buffer (if not already initialised)
26        InitItemBuffer(visibleNodes, visibleGeometry);
27
28        // we need access to the scene manager and the rendersystem
29        PlatformHierarchyInterface *pfHierarchyInterface =
30                dynamic_cast<PlatformHierarchyInterface *>(mHierarchyInterface);
31
32        SceneManager *sm = pfHierarchyInterface->GetSceneManager();
33
34        // ---- Render scene with item buffer (i.e., objects with their id as color codes)
35
36        // const_cast allowed because camera is not changed in renderScene
37        Camera *pCam = const_cast<Camera *>(&camera);
38
39        // disable overlays, reset them later
40        bool overlayEnabled = mViewport->getOverlaysEnabled();
41        mViewport->setOverlaysEnabled(false);
42
43        // set item buffer (must be provided by scene manager)
44        bool useItemBuffer = true;
45        sm->setOption("UseItemBuffer", &useItemBuffer);
46       
47        // clear background with black (i.e., not a valid item id)
48        ColourValue bg = mViewport->getBackgroundColour();
49        mViewport->setBackgroundColour(ColourValue(0, 0, 0, 0));
50
51
52        // --- render item buffer
53        pfHierarchyInterface->GetSceneManager()->_renderScene(pCam, mViewport, false);
54
55
56        //---- collect results
57        int dimx = 0;
58        int dimy = 0;
59
60        // get frame buffer
61        uchar *buf = mViewport->getTarget()->getBufferContents(dimx, dimy);
62
63       
64        // loop through frame buffer & collect visible pixels
65        for (int idx = 0; idx < dimy * dimx * 3; idx += 3)
66        {
67                // -- decode color code to receive id
68                int id = buf[idx] << 16;
69                id += buf[idx + 1] << 8;
70                id += buf[idx + 2];
71
72                // if valid id <= add visibility (id values start at 1
73                if ((id > 0) && (id < (int)visibleGeometry->size()))
74                {
75                        ((*visibleGeometry)[id]).AddVisibility(1, 1);
76                }
77        }
78
79        delete [] buf;
80
81        // ---- render visible nodes and collect node visibility
82        bool renderBoxes = true;
83        sm->setOption("RenderHierarchyNodes", &renderBoxes);
84
85
86        // --- render item buffer for visible nodes only
87        pfHierarchyInterface->GetSceneManager()->_renderScene(pCam, mViewport, false);
88
89
90        // get frame buffer for node visibility
91        buf = mViewport->getTarget()->getBufferContents(dimx, dimy);
92
93       
94        // loop through frame buffer & collect visible pixels
95        for (int idx = 0; idx < dimy * dimx * 3; idx += 3)
96        {
97                // -- decode color code to receive id
98                int id = buf[idx] << 16;
99                id += buf[idx + 1] << 8;
100                id += buf[idx + 2];
101
102                // if valid id <= add visibility (id values start at 1
103                if ((id > 0) && (id < (int)visibleNodes->size()))
104                {
105                        ((*visibleNodes)[id]).AddVisibility(1, 1);
106                }
107        }
108
109        // don't need item buffer anymore
110        useItemBuffer = false;
111        //sm->setOption("UseItemBuffer", &useItemBuffer);
112
113        renderBoxes = false;
114        //sm->setOption("RenderHierarchyNodes", &renderBoxes);
115
116        // reset initialised - flag
117        mWasInitialised = false;
118
119        // reset old overlay status
120        mViewport->setOverlaysEnabled(overlayEnabled);
121       
122        mViewport->setBackgroundColour(bg);
123
124        delete [] buf;
125}
126//-----------------------------------------------------------------------
127void ItemBufferQueryManager::InitItemBuffer(InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
128                            InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry)
129{
130        if (mWasInitialised)
131                return;
132
133        mWasInitialised = true;
134
135        SceneManager *sm =
136                dynamic_cast<PlatformHierarchyInterface *>(mHierarchyInterface)->GetSceneManager();
137
138        SceneManager::EntityIterator it = sm->getEntityIterator();
139
140        // TODO: make this more efficient
141        visibleGeometry->clear();
142        visibleNodes->clear();
143
144        while (it.hasMoreElements())
145        {
146                visibleGeometry->push_back(GtpVisibility::MeshInfo(it.getNext(), 0, 0));
147        }
148
149        // -- initialise hierarchy interface for simple node traversal
150        mHierarchyInterface->InitTraversal(false);
151
152        GtpVisibility::HierarchyNode *node = NULL;
153       
154        int i = 1;
155
156        while (node = mHierarchyInterface->GetNextNode())
157        {
158                mHierarchyInterface->SetNodeId(node, i++);
159                visibleNodes->push_back(GtpVisibility::NodeInfo(node, 0, 0));
160        }
161}
162
163} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.