[133] | 1 | #include "OgrePlatformQueryManager.h" |
---|
| 2 | #include "OcclusionQuery.h" |
---|
| 3 | #include <OgreSceneManager.h> |
---|
| 4 | #include <OgreLogManager.h> |
---|
[140] | 5 | #include <OgreStringConverter.h> |
---|
[133] | 6 | #include <vector> |
---|
[171] | 7 | #include <OgreSubEntity.h> |
---|
[133] | 8 | |
---|
| 9 | |
---|
| 10 | namespace Ogre { |
---|
[171] | 11 | |
---|
[133] | 12 | //----------------------------------------------------------------------- |
---|
[171] | 13 | PlatformQueryManager::PlatformQueryManager(PlatformHierarchyInterface *hierarchyInterface, |
---|
[174] | 14 | Viewport *vp, int queryModes): |
---|
| 15 | QueryManager(hierarchyInterface, queryModes), |
---|
[171] | 16 | mViewport(vp), |
---|
[174] | 17 | mWasInitialised(false) |
---|
[133] | 18 | { |
---|
| 19 | } |
---|
| 20 | //----------------------------------------------------------------------- |
---|
| 21 | bool PlatformQueryManager::ShootRay(const Ray &ray, std::vector<Mesh *> *visibleMeshes, bool isGlobalLine) |
---|
| 22 | { |
---|
| 23 | // run OGRE ray shooting query |
---|
| 24 | return false; |
---|
| 25 | } |
---|
| 26 | //----------------------------------------------------------------------- |
---|
| 27 | void PlatformQueryManager::ComputeFromPointVisibility(const Vector3 &point, |
---|
[316] | 28 | GtpVisibility::NodeInfoContainer *visibleNodes, |
---|
| 29 | GtpVisibility::MeshInfoContainer *visibleGeometry, |
---|
| 30 | GtpVisibility::PatchInfoContainer *visiblePatches, |
---|
[144] | 31 | bool relativeVisibility) |
---|
[133] | 32 | { |
---|
[159] | 33 | SceneManager *sm = dynamic_cast<PlatformHierarchyInterface *> |
---|
| 34 | (mHierarchyInterface)->GetSceneManager(); |
---|
| 35 | |
---|
| 36 | // create a camera for the point query |
---|
[140] | 37 | Camera *cam = sm->createCamera("PointQueryCam"); |
---|
| 38 | |
---|
[141] | 39 | //save old camera |
---|
| 40 | Camera *savedCam = mViewport->getCamera(); |
---|
| 41 | |
---|
| 42 | // --- initialise new camera |
---|
[140] | 43 | mViewport->setCamera(cam); |
---|
| 44 | cam->setPosition(point); |
---|
| 45 | |
---|
[141] | 46 | cam->setNearClipDistance(savedCam->getNearClipDistance()); |
---|
| 47 | cam->setFarClipDistance(savedCam->getFarClipDistance()); |
---|
| 48 | |
---|
[140] | 49 | // set frustum to 45 degrees so all the scene can be captured with 6 shots |
---|
[141] | 50 | cam->setAspectRatio(1.0); |
---|
| 51 | cam->setFOVy(Radian(Math::HALF_PI)); |
---|
| 52 | |
---|
[140] | 53 | int sign = -1; |
---|
| 54 | |
---|
| 55 | // ---- capture visibility from all 6 directions |
---|
[164] | 56 | for (int dir=0; dir < 6; dir++) |
---|
[140] | 57 | { |
---|
| 58 | sign *= -1; |
---|
| 59 | |
---|
| 60 | // Print camera details
|
---|
[141] | 61 | std::stringstream d; |
---|
[140] | 62 | d << "Point query camera: " + StringConverter::toString(cam->getDerivedPosition()) +
|
---|
| 63 | " " + "O: " + StringConverter::toString(cam->getDerivedOrientation()); |
---|
| 64 | LogManager::getSingleton().logMessage(d.str()); |
---|
| 65 | |
---|
[154] | 66 | // prevent from initialising geometry / node array again |
---|
[164] | 67 | if (dir > 0) |
---|
[156] | 68 | { |
---|
[154] | 69 | mWasInitialised = true; |
---|
[156] | 70 | } |
---|
[154] | 71 | |
---|
[171] | 72 | ComputeCameraVisibility(*cam, visibleNodes, visibleGeometry, visiblePatches, |
---|
| 73 | relativeVisibility); |
---|
[159] | 74 | //mViewport->getTarget()->update(); for(int j=0; j<10000000; j++) printf("wait"); |
---|
[141] | 75 | |
---|
| 76 | // permute directions |
---|
[164] | 77 | Vector3 direction(0,0,0); |
---|
| 78 | direction[dir/2] = sign; |
---|
[140] | 79 | |
---|
[164] | 80 | cam->setDirection(direction); |
---|
[140] | 81 | } |
---|
| 82 | |
---|
| 83 | // reset camera |
---|
[141] | 84 | mViewport->setCamera(savedCam); |
---|
[133] | 85 | } |
---|
| 86 | //----------------------------------------------------------------------- |
---|
[171] | 87 | void PlatformQueryManager::ComputeCameraVisibility(const Camera &camera, |
---|
[316] | 88 | GtpVisibility::NodeInfoContainer *visibleNodes, |
---|
| 89 | GtpVisibility::MeshInfoContainer *visibleGeometry, |
---|
| 90 | GtpVisibility::PatchInfoContainer *visiblePatches, |
---|
[171] | 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 |
---|
[173] | 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 | //----------------------------------------------------------------------- |
---|
| 138 | void PlatformQueryManager::CollectItemBufferResults( |
---|
[316] | 139 | GtpVisibility::MeshInfoContainer *visibleGeometry, |
---|
| 140 | GtpVisibility::PatchInfoContainer *visiblePatches) |
---|
[173] | 141 | { |
---|
[171] | 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) |
---|
[174] | 161 | if (mQueryModes == PATCH_VISIBILITY) |
---|
| 162 | { |
---|
| 163 | if ((id > 0) && (id < (int)visiblePatches->size())) |
---|
| 164 | { |
---|
[171] | 165 | ((*visiblePatches)[id]).AddVisibility(1, 0); |
---|
| 166 | } |
---|
[174] | 167 | } |
---|
| 168 | else if (mQueryModes == GEOMETRY_VISIBILITY) |
---|
| 169 | { |
---|
| 170 | if ((id > 0) && (id < (int)visibleGeometry->size())) |
---|
[171] | 171 | { |
---|
| 172 | ((*visibleGeometry)[id]).AddVisibility(1, 0); |
---|
| 173 | } |
---|
| 174 | } |
---|
| 175 | }
|
---|
| 176 |
|
---|
[173] | 177 | delete [] buf;
|
---|
| 178 | }
|
---|
| 179 | |
---|
[171] | 180 | //----------------------------------------------------------------------- |
---|
| 181 | void PlatformQueryManager::InitItemBuffer( |
---|
[316] | 182 | GtpVisibility::MeshInfoContainer *visibleGeometry, |
---|
| 183 | GtpVisibility::PatchInfoContainer *visiblePatches) |
---|
[171] | 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 |
|
---|
[174] | 214 | if (mQueryModes == PATCH_VISIBILITY)
|
---|
[171] | 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 | |
---|
[174] | 224 | if (mQueryModes == GEOMETRY_VISIBILITY) |
---|
[171] | 225 | { |
---|
| 226 | visibleGeometry->push_back(GtpVisibility::MeshInfo(ent, 0, 0)); |
---|
| 227 | ++ id; |
---|
| 228 | } |
---|
| 229 | } |
---|
| 230 | } |
---|
| 231 | //----------------------------------------------------------------------- |
---|
[133] | 232 | void PlatformQueryManager::SetViewport(Viewport *vp) |
---|
| 233 | { |
---|
| 234 | mViewport = vp; |
---|
| 235 | } |
---|
| 236 | } // namespace Ogre |
---|