Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreBspSceneManager.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://ogre.sourceforge.net/
00006 
00007 Copyright © 2000-2002 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreBspSceneManager.h"
00026 #include "OgreBspResourceManager.h"
00027 #include "OgreBspLevel.h"
00028 #include "OgreBspNode.h"
00029 #include "OgreException.h"
00030 #include "OgreRenderSystem.h"
00031 #include "OgreCamera.h"
00032 #include "OgreMaterial.h"
00033 #include "OgrePatchSurface.h"
00034 #include "OgreMesh.h"
00035 #include "OgreSubMesh.h"
00036 #include "OgreMath.h"
00037 #include "OgreControllerManager.h"
00038 #include "OgreLogManager.h"
00039 #include "OgreBspSceneNode.h"
00040 #include "OgreStringConverter.h"
00041 #include "OgreLogManager.h"
00042 #include "OgreTechnique.h"
00043 #include "OgrePass.h"
00044 
00045 
00046 #include <fstream>
00047 
00048 namespace Ogre {
00049 
00050     //-----------------------------------------------------------------------
00051     BspSceneManager::BspSceneManager()
00052     {
00053         // Set features for debugging render
00054         mShowNodeAABs = false;
00055 
00056         // Instantiate BspResourceManager
00057         // Will be managed by singleton
00058         mBspResMgr = new BspResourceManager();
00059 
00060         // No sky by default
00061         mSkyPlaneEnabled = false;
00062         mSkyBoxEnabled = false;
00063         mSkyDomeEnabled = false;
00064 
00065         mLevel = 0;
00066 
00067     }
00068 
00069     //-----------------------------------------------------------------------
00070     BspSceneManager::~BspSceneManager()
00071     {
00072         freeMemory();
00073         delete mBspResMgr;
00074     }
00075 
00076     //-----------------------------------------------------------------------
00077     void BspSceneManager::setWorldGeometry(const String& filename)
00078     {
00079         // Check extension is .bsp
00080         char extension[6];
00081         size_t pos = filename.find_last_of(".");
00082         if( pos == String::npos )
00083             Except(
00084                 Exception::ERR_INVALIDPARAMS,
00085                 "Unable to load world geometry. Invalid extension (must be .bsp).",
00086                 "BspSceneManager::setWorldGeometry");
00087 
00088         strcpy(extension, filename.substr(pos + 1, filename.length() - pos).c_str());
00089 
00090         if (stricmp(extension, "bsp"))
00091             Except(Exception::ERR_INVALIDPARAMS,
00092             "Unable to load world geometry. Invalid extension (must be .bsp).",
00093             "BspSceneManager::setWorldGeometry");
00094 
00095         // Load using resource manager
00096         mLevel = BspResourceManager::getSingleton().load(filename);
00097 
00098         // Init static render operation
00099         mRenderOp.vertexData = mLevel->mVertexData;
00100         // index data is per-frame
00101         mRenderOp.indexData = new IndexData();
00102         mRenderOp.indexData->indexStart = 0;
00103         mRenderOp.indexData->indexCount = 0;
00104         // Create enough index space to render whole level
00105         mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton()
00106             .createIndexBuffer(
00107                 HardwareIndexBuffer::IT_32BIT, // always 32-bit
00108                 mLevel->mNumIndexes, 
00109                 HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false);
00110 
00111         mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST;
00112         mRenderOp.useIndexes = true;
00113 
00114 
00115     }
00116     //-----------------------------------------------------------------------
00117     void BspSceneManager::_findVisibleObjects(Camera* cam, bool onlyShadowCasters)
00118     {
00119         // Clear unique list of movables for this frame
00120         mMovablesForRendering.clear();
00121         // Walk the tree, tag static geometry, return camera's node (for info only)
00122         // Movables are now added to the render queue in processVisibleLeaf
00123         BspNode* cameraNode = walkTree(cam, onlyShadowCasters);
00124 
00125 
00126     }
00127     //-----------------------------------------------------------------------
00128     void BspSceneManager::renderStaticGeometry(void)
00129     {
00130         // Cache vertex/face data first
00131         std::vector<StaticFaceGroup*>::const_iterator faceGrpi;
00132         static RenderOperation patchOp;
00133         
00134         // no world transform required
00135         mDestRenderSystem->_setWorldMatrix(Matrix4::IDENTITY);
00136         // Set view / proj
00137         mDestRenderSystem->_setViewMatrix(mCameraInProgress->getViewMatrix());
00138         mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrix());
00139 
00140         // For each material in turn, cache rendering data & render
00141         MaterialFaceGroupMap::const_iterator mati;
00142 
00143         for (mati = mMatFaceGroupMap.begin(); mati != mMatFaceGroupMap.end(); ++mati)
00144         {
00145             // Get Material
00146             Material* thisMaterial = mati->first;
00147 
00148             // Empty existing cache
00149             mRenderOp.indexData->indexCount = 0;
00150             // lock index buffer ready to receive data
00151             unsigned int* pIdx = static_cast<unsigned int*>(
00152                 mRenderOp.indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
00153 
00154             for (faceGrpi = mati->second.begin(); faceGrpi != mati->second.end(); ++faceGrpi)
00155             {
00156                 // Cache each
00157                 unsigned int numelems = cacheGeometry(pIdx, *faceGrpi);
00158                 mRenderOp.indexData->indexCount += numelems;
00159                 pIdx += numelems;
00160             }
00161             // Unlock the buffer
00162             mRenderOp.indexData->indexBuffer->unlock();
00163 
00164             // Skip if no faces to process (we're not doing flare types yet)
00165             if (mRenderOp.indexData->indexCount == 0)
00166                 continue;
00167 
00168             Technique::PassIterator pit = thisMaterial->getTechnique(0)->getPassIterator();
00169 
00170             while (pit.hasMoreElements())
00171             {
00172                 setPass(pit.getNext());
00173 
00174                 mDestRenderSystem->_render(mRenderOp);
00175 
00176 
00177             } 
00178 
00179 
00180         } // for each material
00181 
00182         /*
00183         if (mShowNodeAABs)
00184         {
00185             mDestRenderSystem->_render(mAABGeometry);
00186         }
00187         */
00188     }
00189     //-----------------------------------------------------------------------
00190     void BspSceneManager::_renderVisibleObjects(void)
00191     {
00192         // Render static level geometry first
00193         renderStaticGeometry();
00194 
00195         // Call superclass to render the rest
00196         SceneManager::_renderVisibleObjects();
00197 
00198     }
00199 
00200     //-----------------------------------------------------------------------
00201     // REMOVE THIS CRAP
00202     //-----------------------------------------------------------------------
00203     // Temp debug lines
00204     bool firstTime = true;
00205     std::ofstream of;
00206     //-----------------------------------------------------------------------
00207     //-----------------------------------------------------------------------
00208     //-----------------------------------------------------------------------
00209     BspNode* BspSceneManager::walkTree(Camera* camera, bool onlyShadowCasters)
00210     {
00211         // Locate the leaf node where the camera is located
00212         BspNode* cameraNode = mLevel->findLeaf(camera->getDerivedPosition());
00213 
00214         mMatFaceGroupMap.clear();
00215         mFaceGroupSet.clear();
00216 
00217         // Scan through all the other leaf nodes looking for visibles
00218         int i = mLevel->mNumNodes - mLevel->mLeafStart;
00219         BspNode* nd = mLevel->mRootNode + mLevel->mLeafStart;
00220 
00221         /*
00222         if (firstTime)
00223         {
00224             camera->getViewMatrix(); // Force update view before report
00225             of.open("BspSceneManager.log");
00226             of << *camera << std::endl;
00227             of << "Camera Node: " << *cameraNode << std::endl;
00228             of << "Vertex Data: " << std::endl;
00229             for (int testi = 0; testi < mLevel->mNumVertices; ++testi)
00230             {
00231                 of << " " << testi << ": pos(" <<
00232                   mLevel->mVertices[testi].position[0] << ", " <<
00233                     mLevel->mVertices[testi].position[1] << ", " << mLevel->mVertices[testi].position[2] << ")" <<
00234                     " uv(" << mLevel->mVertices[testi].texcoords[0] << ", " << mLevel->mVertices[testi].texcoords[1] << ")" <<
00235                     " lm(" << mLevel->mVertices[testi].lightmap[0] << ", " << mLevel->mVertices[testi].lightmap[1] << ")" << std::endl;
00236             }
00237             of << "Element data:" << std::endl;
00238             for (testi = 0; testi < mLevel->mNumElements; ++testi)
00239             {
00240                 of << " " << testi << ": " << mLevel->mElements[testi] << std::endl;
00241 
00242             }
00243         }
00244         */
00245 
00246         while (i--)
00247         {
00248             if (mLevel->isLeafVisible(cameraNode, nd))
00249             {
00250 
00251                 // Visible according to PVS, check bounding box against frustum
00252                 FrustumPlane plane;
00253                 if (camera->isVisible(nd->getBoundingBox(), &plane))
00254                 {
00255                     //if (firstTime)
00256                     //{
00257                     //    of << "Visible Node: " << *nd << std::endl;
00258                     //}
00259                     processVisibleLeaf(nd, camera, onlyShadowCasters);
00260                     if (mShowNodeAABs)
00261                         addBoundingBox(nd->getBoundingBox(), true);
00262                 }
00263             }
00264             nd++;
00265         }
00266 
00267 
00268         // TEST
00269         //if (firstTime)
00270         //{
00271         //    of.close();
00272         //    firstTime = false;
00273         //}
00274         return cameraNode;
00275 
00276     }
00277     //-----------------------------------------------------------------------
00278     void BspSceneManager::processVisibleLeaf(BspNode* leaf, Camera* cam, bool onlyShadowCasters)
00279     {
00280         Material* pMat;
00281         // Skip world geometry if we're only supposed to process shadow casters
00282         // World is pre-lit
00283         if (!onlyShadowCasters)
00284         {
00285             // Parse the leaf node's faces, add face groups to material map
00286             int numGroups = leaf->getNumFaceGroups();
00287             int idx = leaf->getFaceGroupStart();
00288 
00289             while (numGroups--)
00290             {
00291                 int realIndex = mLevel->mLeafFaceGroups[idx++];
00292                 // Check not already included
00293                 if (mFaceGroupSet.find(realIndex) != mFaceGroupSet.end())
00294                     continue;
00295                 StaticFaceGroup* faceGroup = mLevel->mFaceGroups + realIndex;
00296                 // Get Material pointer by handle
00297                 pMat = getMaterial(faceGroup->materialHandle);
00298                 // Check normal (manual culling)
00299                 ManualCullingMode cullMode = pMat->getTechnique(0)->getPass(0)->getManualCullingMode();
00300                 if (cullMode != MANUAL_CULL_NONE)
00301                 {
00302                     Real dist = faceGroup->plane.getDistance(cam->getDerivedPosition());
00303                     if ( (dist < 0 && cullMode == MANUAL_CULL_BACK) ||
00304                         (dist > 0 && cullMode == MANUAL_CULL_FRONT) )
00305                         continue; // skip
00306                 }
00307                 mFaceGroupSet.insert(realIndex);
00308                 // Try to insert, will find existing if already there
00309                 std::pair<MaterialFaceGroupMap::iterator, bool> matgrpi;
00310                 matgrpi = mMatFaceGroupMap.insert(
00311                     MaterialFaceGroupMap::value_type(pMat, std::vector<StaticFaceGroup*>())
00312                     );
00313                 // Whatever happened, matgrpi.first is map iterator
00314                 // Need to get second part of that to get vector
00315                 matgrpi.first->second.push_back(faceGroup);
00316 
00317                 //if (firstTime)
00318                 //{
00319                 //    of << "  Emitting faceGroup: index=" << realIndex << ", " << *faceGroup << std::endl;
00320                 //}
00321             }
00322         }
00323 
00324         // Add movables to render queue, provided it hasn't been seen already
00325         const BspNode::IntersectingObjectSet& objects = leaf->getObjects();
00326         BspNode::IntersectingObjectSet::const_iterator oi, oiend;
00327         oiend = objects.end();
00328         for (oi = objects.begin(); oi != oiend; ++oi)
00329         {
00330             if (mMovablesForRendering.find(*oi) == mMovablesForRendering.end())
00331             {
00332                 // It hasn't been seen yet
00333                 MovableObject *mov = const_cast<MovableObject*>(*oi); // hacky
00334                 if (mov->isVisible() && 
00335                     (!onlyShadowCasters || mov->getCastShadows()) && 
00336                     cam->isVisible(mov->getWorldBoundingBox()))
00337                 {
00338                     mov->_notifyCurrentCamera(cam);
00339                     mov->_updateRenderQueue(getRenderQueue());
00340                     // Check if the bounding box should be shown.
00341                     SceneNode* sn = static_cast<SceneNode*>(mov->getParentNode());
00342                     if (sn->getShowBoundingBox() || mShowBoundingBoxes)
00343                     {
00344                         sn->_addBoundingBoxToQueue(getRenderQueue());
00345                     }
00346                     mMovablesForRendering.insert(*oi);
00347                 }
00348 
00349             }
00350         }
00351 
00352 
00353     }
00354     //-----------------------------------------------------------------------
00355     unsigned int BspSceneManager::cacheGeometry(unsigned int* pIndexes, 
00356         const StaticFaceGroup* faceGroup)
00357     {
00358         // Skip sky always
00359         if (faceGroup->isSky)
00360             return 0;
00361 
00362         size_t idxStart, numIdx, vertexStart;
00363 
00364         if (faceGroup->fType == FGT_FACE_LIST)
00365         {
00366             idxStart = faceGroup->elementStart;
00367             numIdx = faceGroup->numElements;
00368             vertexStart = faceGroup->vertexStart;
00369         }
00370         else if (faceGroup->fType == FGT_PATCH)
00371         {
00372 
00373             idxStart = faceGroup->patchSurf->getIndexOffset();
00374             numIdx = faceGroup->patchSurf->getCurrentIndexCount();
00375             vertexStart = faceGroup->patchSurf->getVertexOffset();
00376         }
00377         else
00378         {
00379             // Unsupported face type
00380             return 0;
00381         }
00382 
00383 
00384         // Copy index data
00385         unsigned int* pSrc = static_cast<unsigned int*>(
00386             mLevel->mIndexes->lock(
00387                 idxStart * sizeof(unsigned int),
00388                 numIdx * sizeof(unsigned int), 
00389                 HardwareBuffer::HBL_READ_ONLY));
00390         // Offset the indexes here
00391         // we have to do this now rather than up-front because the 
00392         // indexes are sometimes reused to address different vertex chunks
00393         for (size_t elem = 0; elem < numIdx; ++elem)
00394         {
00395             *pIndexes++ = *pSrc++ + vertexStart;
00396         }
00397         mLevel->mIndexes->unlock();
00398 
00399         // return number of elements
00400         return static_cast<unsigned int>(numIdx);
00401 
00402 
00403     }
00404 
00405     //-----------------------------------------------------------------------
00406     void BspSceneManager::freeMemory(void)
00407     {
00408         // no need to delete index buffer, will be handled by shared pointer
00409         //delete mRenderOp.indexData; // causing an error right now?
00410     }
00411     //-----------------------------------------------------------------------
00412     void BspSceneManager::showNodeBoxes(bool show)
00413     {
00414         mShowNodeAABs = show;
00415     }
00416     //-----------------------------------------------------------------------
00417     void BspSceneManager::addBoundingBox(AxisAlignedBox& aab, bool visible)
00418     {
00419         /*
00420         unsigned long visibleColour;
00421         unsigned long nonVisibleColour;
00422         Root& r = Root::getSingleton();
00423 
00424         r.convertColourValue(ColourValue::White, &visibleColour);
00425         r.convertColourValue(ColourValue::Blue, &nonVisibleColour);
00426         if (mShowNodeAABs)
00427         {
00428             // Add set of lines
00429             Real* pVertices = (Real*)mAABGeometry.pVertices + (mAABGeometry.numVertices*3);
00430             unsigned short* pIndexes = mAABGeometry.pIndexes + mAABGeometry.numIndexes;
00431             unsigned long* pColours = (unsigned long*)mAABGeometry.pDiffuseColour + mAABGeometry.numVertices;
00432 
00433             const Vector3* pCorner = aab.getAllCorners();
00434 
00435             int i;
00436             for (i = 0; i < 8; ++i)
00437             {
00438                 *pVertices++ = pCorner->x;
00439                 *pVertices++ = pCorner->y;
00440                 *pVertices++ = pCorner->z;
00441                 pCorner++;
00442 
00443                 if (visible)
00444                 {
00445                     *pColours++ = visibleColour;
00446                 }
00447                 else
00448                 {
00449                     *pColours++ = nonVisibleColour;
00450                 }
00451 
00452             }
00453 
00454             *pIndexes++ = 0 + mAABGeometry.numVertices;
00455             *pIndexes++ = 1 + mAABGeometry.numVertices;
00456             *pIndexes++ = 1 + mAABGeometry.numVertices;
00457             *pIndexes++ = 2 + mAABGeometry.numVertices;
00458             *pIndexes++ = 2 + mAABGeometry.numVertices;
00459             *pIndexes++ = 3 + mAABGeometry.numVertices;
00460             *pIndexes++ = 3 + mAABGeometry.numVertices;
00461             *pIndexes++ = 1 + mAABGeometry.numVertices;
00462             *pIndexes++ = 4 + mAABGeometry.numVertices;
00463             *pIndexes++ = 5 + mAABGeometry.numVertices;
00464             *pIndexes++ = 5 + mAABGeometry.numVertices;
00465             *pIndexes++ = 6 + mAABGeometry.numVertices;
00466             *pIndexes++ = 6 + mAABGeometry.numVertices;
00467             *pIndexes++ = 7 + mAABGeometry.numVertices;
00468             *pIndexes++ = 7 + mAABGeometry.numVertices;
00469             *pIndexes++ = 4 + mAABGeometry.numVertices;
00470             *pIndexes++ = 1 + mAABGeometry.numVertices;
00471             *pIndexes++ = 5 + mAABGeometry.numVertices;
00472             *pIndexes++ = 2 + mAABGeometry.numVertices;
00473             *pIndexes++ = 4 + mAABGeometry.numVertices;
00474             *pIndexes++ = 0 + mAABGeometry.numVertices;
00475             *pIndexes++ = 6 + mAABGeometry.numVertices;
00476             *pIndexes++ = 3 + mAABGeometry.numVertices;
00477             *pIndexes++ = 7 + mAABGeometry.numVertices;
00478 
00479 
00480             mAABGeometry.numVertices += 8;
00481             mAABGeometry.numIndexes += 24;
00482 
00483 
00484         }
00485         */
00486 
00487     }
00488     //-----------------------------------------------------------------------
00489     ViewPoint BspSceneManager::getSuggestedViewpoint(bool random)
00490     {
00491         if (!mLevel || mLevel->mPlayerStarts.size() == 0)
00492         {
00493             // No level, use default
00494             return SceneManager::getSuggestedViewpoint(random);
00495         }
00496         else
00497         {
00498             if (random)
00499             {
00500                 size_t idx = (size_t)( Math::UnitRandom() * mLevel->mPlayerStarts.size() );
00501                 return mLevel->mPlayerStarts[idx];
00502             }
00503             else
00504             {
00505                 return mLevel->mPlayerStarts[0];
00506             }
00507 
00508 
00509         }
00510 
00511     }
00512     //-----------------------------------------------------------------------
00513     SceneNode * BspSceneManager::createSceneNode( void )
00514     {
00515         BspSceneNode * sn = new BspSceneNode( this );
00516         mSceneNodes[ sn->getName() ] = sn;
00517         return sn;
00518     }
00519     //-----------------------------------------------------------------------
00520     SceneNode * BspSceneManager::createSceneNode( const String &name )
00521     {
00522         BspSceneNode * sn = new BspSceneNode( this, name );
00523         mSceneNodes[ sn->getName() ] = sn;
00524         return sn;
00525     }
00526     //-----------------------------------------------------------------------
00527     void BspSceneManager::_notifyObjectMoved(const MovableObject* mov, 
00528         const Vector3& pos)
00529     {
00530         mLevel->_notifyObjectMoved(mov, pos);
00531     }
00532     //-----------------------------------------------------------------------
00533     void BspSceneManager::_notifyObjectDetached(const MovableObject* mov)
00534     {
00535         mLevel->_notifyObjectDetached(mov);
00536     }
00537     //-----------------------------------------------------------------------
00538     /*
00539     AxisAlignedBoxSceneQuery* BspSceneManager::
00540     createAABBQuery(const AxisAlignedBox& box, unsigned long mask)
00541     {
00542         // TODO
00543         return NULL;
00544     }
00545     //-----------------------------------------------------------------------
00546     SphereSceneQuery* BspSceneManager::
00547     createSphereQuery(const Sphere& sphere, unsigned long mask)
00548     {
00549         // TODO
00550         return NULL;
00551     }
00552     //-----------------------------------------------------------------------
00553     RaySceneQuery* BspSceneManager::
00554     createRayQuery(const Ray& ray, unsigned long mask)
00555     {
00556         // TODO
00557         return NULL;
00558     }
00559     */
00560     //-----------------------------------------------------------------------
00561     IntersectionSceneQuery* BspSceneManager::
00562     createIntersectionQuery(unsigned long mask)
00563     {
00564         BspIntersectionSceneQuery* q = new BspIntersectionSceneQuery(this);
00565         q->setQueryMask(mask);
00566         return q;
00567     }
00568     //-----------------------------------------------------------------------
00569     //-----------------------------------------------------------------------
00570     BspIntersectionSceneQuery::BspIntersectionSceneQuery(SceneManager* creator) 
00571         : DefaultIntersectionSceneQuery(creator)
00572     {
00573         // Add bounds fragment type
00574         mSupportedWorldFragments.insert(SceneQuery::WFT_PLANE_BOUNDED_REGION);
00575         
00576     }
00577     void BspIntersectionSceneQuery::execute(IntersectionSceneQueryListener* listener)
00578     {
00579         /*
00580         Go through each leaf node in BspLevel and check movables against each other and world
00581         Issue: some movable-movable intersections could be reported twice if 2 movables
00582         overlap 2 leaves?
00583         */
00584         BspLevel* lvl = ((BspSceneManager*)mParentSceneMgr)->getLevel();
00585         BspNode* leaf = lvl->getLeafStart();
00586         int numLeaves = lvl->getNumLeaves();
00587         
00588         while (numLeaves--)
00589         {
00590             const BspNode::IntersectingObjectSet& objects = leaf->getObjects();
00591             int numObjects = (int)objects.size();
00592 
00593             BspNode::IntersectingObjectSet::const_iterator a, b, theEnd;
00594             theEnd = objects.end();
00595             a = objects.begin();
00596             for (int oi = 0; oi < numObjects; ++oi, ++a)
00597             {
00598                 const MovableObject* aObj = *a;
00599                 // Skip this object if collision not enabled
00600                 if (!(aObj->getQueryFlags() & mQueryMask))
00601                     continue;
00602 
00603                 if (oi < (numObjects-1))
00604                 {
00605                     // Check object against others in this node
00606                     b = a;
00607                     for (++b; b != theEnd; ++b)
00608                     {
00609                         const MovableObject* bObj = *b;
00610                         // Apply mask to b (both must pass)
00611                         if ( bObj->getQueryFlags() & mQueryMask)
00612                         {
00613                             const AxisAlignedBox& box1 = aObj->getWorldBoundingBox();
00614                             const AxisAlignedBox& box2 = bObj->getWorldBoundingBox();
00615 
00616                             if (box1.intersects(box2))
00617                             {
00618                                 listener->queryResult(const_cast<MovableObject*>(aObj), 
00619                                     const_cast<MovableObject*>(bObj)); // hacky
00620                             }
00621                         }
00622                     }
00623                 }
00624                 // Check object against brushes
00625                 const BspNode::NodeBrushList& brushes = leaf->getSolidBrushes();
00626                 BspNode::NodeBrushList::const_iterator bi, biend;
00627                 biend = brushes.end();
00628                 Real radius = aObj->getBoundingRadius();
00629                 const Vector3& pos = aObj->getParentNode()->_getDerivedPosition();
00630 
00631                 for (bi = brushes.begin(); bi != biend; ++bi)
00632                 {
00633                     std::list<Plane>::const_iterator planeit, planeitend;
00634                     planeitend = (*bi)->planes.end();
00635                     bool brushIntersect = true; // Assume intersecting for now
00636 
00637                     for (planeit = (*bi)->planes.begin(); planeit != planeitend; ++planeit)
00638                     {
00639                         Real dist = planeit->getDistance(pos);
00640                         if (dist > radius)
00641                         {
00642                             // Definitely excluded
00643                             brushIntersect = false;
00644                             break;
00645                         }
00646                     }
00647                     if (brushIntersect)
00648                     {
00649                         // report this brush as it's WorldFragment
00650                         assert((*bi)->fragment.fragmentType == SceneQuery::WFT_PLANE_BOUNDED_REGION);
00651                         listener->queryResult(const_cast<MovableObject*>(aObj), // hacky
00652                                 const_cast<WorldFragment*>(&((*bi)->fragment))); 
00653                     }
00654 
00655                 }
00656 
00657 
00658             }
00659 
00660             ++leaf;
00661         }
00662 
00663 
00664 
00665     }
00666 }
00667 

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:16 2004