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