#include "OgreItemBufferQueryManager.h" #include #include #include namespace Ogre { //----------------------------------------------------------------------- ItemBufferQueryManager::ItemBufferQueryManager(PlatformHierarchyInterface *hierarchyInterface, Viewport *vp): PlatformQueryManager(hierarchyInterface, vp) { } //----------------------------------------------------------------------- bool ItemBufferQueryManager::ShootRay(const Ray &ray, std::vector *visibleMeshes, bool isGlobalLine) { // run OGRE ray shooting query return false; } //----------------------------------------------------------------------- void ItemBufferQueryManager::ComputeCameraVisibility(const Camera &camera, InfoContainer *visibleNodes, InfoContainer *visibleGeometry, bool relativeVisibility) { // initialise item buffer (if not already initialised) InitItemBuffer(visibleNodes, visibleGeometry); // we need access to the scene manager and the rendersystem PlatformHierarchyInterface *pfHierarchyInterface = dynamic_cast(mHierarchyInterface); SceneManager *sm = pfHierarchyInterface->GetSceneManager(); // ---- Render scene with item buffer (i.e., objects with their id as color codes) // const_cast allowed because camera is not changed in renderScene Camera *pCam = const_cast(&camera); // disable overlays, reset them later bool overlayEnabled = mViewport->getOverlaysEnabled(); mViewport->setOverlaysEnabled(false); // set item buffer (must be provided by scene manager) bool useItemBuffer = true; sm->setOption("UseItemBuffer", &useItemBuffer); // clear background with black (i.e., not a valid item id) ColourValue bg = mViewport->getBackgroundColour(); mViewport->setBackgroundColour(ColourValue(0, 0, 0, 0)); // --- render item buffer pfHierarchyInterface->GetSceneManager()->_renderScene(pCam, mViewport, false); //---- collect results int dimx = 0; int dimy = 0; // get frame buffer uchar *buf = mViewport->getTarget()->getBufferContents(dimx, dimy); // loop through frame buffer & collect visible pixels for (int idx = 0; idx < dimy * dimx * 3; idx += 3) { // -- decode color code to receive id int id = buf[idx] << 16; id += buf[idx + 1] << 8; id += buf[idx + 2]; // if valid id <= add visibility (id values start at 1 if ((id > 0) && (id < (int)visibleGeometry->size())) { ((*visibleGeometry)[id]).AddVisibility(1, 1); } } //-- reset options // don't need item buffer anymore useItemBuffer = false; sm->setOption("UseItemBuffer", &useItemBuffer); // reset initialised - flag mWasInitialised = false; // reset old overlay status mViewport->setOverlaysEnabled(overlayEnabled); // reset background color mViewport->setBackgroundColour(bg); // delete array storing the frame buffer delete [] buf; } //----------------------------------------------------------------------- void ItemBufferQueryManager::InitItemBuffer(InfoContainer *visibleNodes, InfoContainer *visibleGeometry) { if (mWasInitialised) return; mWasInitialised = true; SceneManager *sm = dynamic_cast(mHierarchyInterface)->GetSceneManager(); SceneManager::EntityIterator it = sm->getEntityIterator(); // TODO: make this more efficient visibleGeometry->clear(); visibleNodes->clear(); while (it.hasMoreElements()) { visibleGeometry->push_back(GtpVisibility::MeshInfo(it.getNext(), 0, 0)); } } } // namespace Ogre