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, false); 00110 00111 mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; 00112 mRenderOp.useIndexes = true; 00113 00114 00115 } 00116 //----------------------------------------------------------------------- 00117 void BspSceneManager::_findVisibleObjects(Camera* cam) 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); 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) 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); 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) 00279 { 00280 Material* pMat; 00281 // Parse the leaf node's faces, add face groups to material map 00282 int numGroups = leaf->getNumFaceGroups(); 00283 int idx = leaf->getFaceGroupStart(); 00284 00285 while (numGroups--) 00286 { 00287 int realIndex = mLevel->mLeafFaceGroups[idx++]; 00288 // Check not already included 00289 if (mFaceGroupSet.find(realIndex) != mFaceGroupSet.end()) 00290 continue; 00291 StaticFaceGroup* faceGroup = mLevel->mFaceGroups + realIndex; 00292 // Get Material pointer by handle 00293 pMat = getMaterial(faceGroup->materialHandle); 00294 // Check normal (manual culling) 00295 ManualCullingMode cullMode = pMat->getTechnique(0)->getPass(0)->getManualCullingMode(); 00296 if (cullMode != MANUAL_CULL_NONE) 00297 { 00298 Real dist = faceGroup->plane.getDistance(cam->getDerivedPosition()); 00299 if ( (dist < 0 && cullMode == MANUAL_CULL_BACK) || 00300 (dist > 0 && cullMode == MANUAL_CULL_FRONT) ) 00301 continue; // skip 00302 } 00303 mFaceGroupSet.insert(realIndex); 00304 // Try to insert, will find existing if already there 00305 std::pair<MaterialFaceGroupMap::iterator, bool> matgrpi; 00306 matgrpi = mMatFaceGroupMap.insert( 00307 MaterialFaceGroupMap::value_type(pMat, std::vector<StaticFaceGroup*>()) 00308 ); 00309 // Whatever happened, matgrpi.first is map iterator 00310 // Need to get second part of that to get vector 00311 matgrpi.first->second.push_back(faceGroup); 00312 00313 //if (firstTime) 00314 //{ 00315 // of << " Emitting faceGroup: index=" << realIndex << ", " << *faceGroup << std::endl; 00316 //} 00317 } 00318 00319 // Add movables to render queue, provided it hasn't been seen already 00320 const BspNode::IntersectingObjectSet& objects = leaf->getObjects(); 00321 BspNode::IntersectingObjectSet::const_iterator oi, oiend; 00322 oiend = objects.end(); 00323 for (oi = objects.begin(); oi != oiend; ++oi) 00324 { 00325 if (mMovablesForRendering.find(*oi) == mMovablesForRendering.end()) 00326 { 00327 // It hasn't been seen yet 00328 MovableObject *mov = const_cast<MovableObject*>(*oi); // hacky 00329 if (mov->isVisible() && 00330 cam->isVisible(mov->getWorldBoundingBox())) 00331 { 00332 mov->_notifyCurrentCamera(cam); 00333 mov->_updateRenderQueue(&mRenderQueue); 00334 // Check if the bounding box should be shown. 00335 SceneNode* sn = static_cast<SceneNode*>(mov->getParentNode()); 00336 if (sn->getShowBoundingBox() || mShowBoundingBoxes) 00337 { 00338 sn->_addBoundingBoxToQueue(&mRenderQueue); 00339 } 00340 mMovablesForRendering.insert(*oi); 00341 } 00342 00343 } 00344 } 00345 00346 00347 } 00348 //----------------------------------------------------------------------- 00349 unsigned int BspSceneManager::cacheGeometry(unsigned int* pIndexes, 00350 const StaticFaceGroup* faceGroup) 00351 { 00352 // Skip sky always 00353 if (faceGroup->isSky) 00354 return 0; 00355 00356 size_t idxStart, numIdx, vertexStart; 00357 00358 if (faceGroup->fType == FGT_FACE_LIST) 00359 { 00360 idxStart = faceGroup->elementStart; 00361 numIdx = faceGroup->numElements; 00362 vertexStart = faceGroup->vertexStart; 00363 } 00364 else if (faceGroup->fType == FGT_PATCH) 00365 { 00366 00367 idxStart = faceGroup->patchSurf->getIndexOffset(); 00368 numIdx = faceGroup->patchSurf->getCurrentIndexCount(); 00369 vertexStart = faceGroup->patchSurf->getVertexOffset(); 00370 } 00371 else 00372 { 00373 // Unsupported face type 00374 return 0; 00375 } 00376 00377 00378 // Copy index data 00379 unsigned int* pSrc = static_cast<unsigned int*>( 00380 mLevel->mIndexes->lock( 00381 idxStart * sizeof(unsigned int), 00382 numIdx * sizeof(unsigned int), 00383 HardwareBuffer::HBL_READ_ONLY)); 00384 // Offset the indexes here 00385 // we have to do this now rather than up-front because the 00386 // indexes are sometimes reused to address different vertex chunks 00387 for (size_t elem = 0; elem < numIdx; ++elem) 00388 { 00389 *pIndexes++ = *pSrc++ + vertexStart; 00390 } 00391 mLevel->mIndexes->unlock(); 00392 00393 // return number of elements 00394 return static_cast<unsigned int>(numIdx); 00395 00396 00397 } 00398 00399 //----------------------------------------------------------------------- 00400 void BspSceneManager::freeMemory(void) 00401 { 00402 // no need to delete index buffer, will be handled by shared pointer 00403 //delete mRenderOp.indexData; // causing an error right now? 00404 } 00405 //----------------------------------------------------------------------- 00406 void BspSceneManager::showNodeBoxes(bool show) 00407 { 00408 mShowNodeAABs = show; 00409 } 00410 //----------------------------------------------------------------------- 00411 void BspSceneManager::addBoundingBox(AxisAlignedBox& aab, bool visible) 00412 { 00413 /* 00414 unsigned long visibleColour; 00415 unsigned long nonVisibleColour; 00416 Root& r = Root::getSingleton(); 00417 00418 r.convertColourValue(ColourValue::White, &visibleColour); 00419 r.convertColourValue(ColourValue::Blue, &nonVisibleColour); 00420 if (mShowNodeAABs) 00421 { 00422 // Add set of lines 00423 Real* pVertices = (Real*)mAABGeometry.pVertices + (mAABGeometry.numVertices*3); 00424 unsigned short* pIndexes = mAABGeometry.pIndexes + mAABGeometry.numIndexes; 00425 unsigned long* pColours = (unsigned long*)mAABGeometry.pDiffuseColour + mAABGeometry.numVertices; 00426 00427 const Vector3* pCorner = aab.getAllCorners(); 00428 00429 int i; 00430 for (i = 0; i < 8; ++i) 00431 { 00432 *pVertices++ = pCorner->x; 00433 *pVertices++ = pCorner->y; 00434 *pVertices++ = pCorner->z; 00435 pCorner++; 00436 00437 if (visible) 00438 { 00439 *pColours++ = visibleColour; 00440 } 00441 else 00442 { 00443 *pColours++ = nonVisibleColour; 00444 } 00445 00446 } 00447 00448 *pIndexes++ = 0 + mAABGeometry.numVertices; 00449 *pIndexes++ = 1 + mAABGeometry.numVertices; 00450 *pIndexes++ = 1 + mAABGeometry.numVertices; 00451 *pIndexes++ = 2 + mAABGeometry.numVertices; 00452 *pIndexes++ = 2 + mAABGeometry.numVertices; 00453 *pIndexes++ = 3 + mAABGeometry.numVertices; 00454 *pIndexes++ = 3 + mAABGeometry.numVertices; 00455 *pIndexes++ = 1 + mAABGeometry.numVertices; 00456 *pIndexes++ = 4 + mAABGeometry.numVertices; 00457 *pIndexes++ = 5 + mAABGeometry.numVertices; 00458 *pIndexes++ = 5 + mAABGeometry.numVertices; 00459 *pIndexes++ = 6 + mAABGeometry.numVertices; 00460 *pIndexes++ = 6 + mAABGeometry.numVertices; 00461 *pIndexes++ = 7 + mAABGeometry.numVertices; 00462 *pIndexes++ = 7 + mAABGeometry.numVertices; 00463 *pIndexes++ = 4 + mAABGeometry.numVertices; 00464 *pIndexes++ = 1 + mAABGeometry.numVertices; 00465 *pIndexes++ = 5 + mAABGeometry.numVertices; 00466 *pIndexes++ = 2 + mAABGeometry.numVertices; 00467 *pIndexes++ = 4 + mAABGeometry.numVertices; 00468 *pIndexes++ = 0 + mAABGeometry.numVertices; 00469 *pIndexes++ = 6 + mAABGeometry.numVertices; 00470 *pIndexes++ = 3 + mAABGeometry.numVertices; 00471 *pIndexes++ = 7 + mAABGeometry.numVertices; 00472 00473 00474 mAABGeometry.numVertices += 8; 00475 mAABGeometry.numIndexes += 24; 00476 00477 00478 } 00479 */ 00480 00481 } 00482 //----------------------------------------------------------------------- 00483 ViewPoint BspSceneManager::getSuggestedViewpoint(bool random) 00484 { 00485 if (!mLevel || mLevel->mPlayerStarts.size() == 0) 00486 { 00487 // No level, use default 00488 return SceneManager::getSuggestedViewpoint(random); 00489 } 00490 else 00491 { 00492 if (random) 00493 { 00494 size_t idx = (size_t)( Math::UnitRandom() * mLevel->mPlayerStarts.size() ); 00495 return mLevel->mPlayerStarts[idx]; 00496 } 00497 else 00498 { 00499 return mLevel->mPlayerStarts[0]; 00500 } 00501 00502 00503 } 00504 00505 } 00506 //----------------------------------------------------------------------- 00507 SceneNode * BspSceneManager::createSceneNode( void ) 00508 { 00509 BspSceneNode * sn = new BspSceneNode( this ); 00510 mSceneNodes[ sn->getName() ] = sn; 00511 return sn; 00512 } 00513 //----------------------------------------------------------------------- 00514 SceneNode * BspSceneManager::createSceneNode( const String &name ) 00515 { 00516 BspSceneNode * sn = new BspSceneNode( this, name ); 00517 mSceneNodes[ sn->getName() ] = sn; 00518 return sn; 00519 } 00520 //----------------------------------------------------------------------- 00521 void BspSceneManager::_notifyObjectMoved(const MovableObject* mov, 00522 const Vector3& pos) 00523 { 00524 mLevel->_notifyObjectMoved(mov, pos); 00525 } 00526 //----------------------------------------------------------------------- 00527 void BspSceneManager::_notifyObjectDetached(const MovableObject* mov) 00528 { 00529 mLevel->_notifyObjectDetached(mov); 00530 } 00531 //----------------------------------------------------------------------- 00532 AxisAlignedBoxSceneQuery* BspSceneManager:: 00533 createAABBQuery(const AxisAlignedBox& box, unsigned long mask) 00534 { 00535 // TODO 00536 return NULL; 00537 } 00538 //----------------------------------------------------------------------- 00539 SphereSceneQuery* BspSceneManager:: 00540 createSphereQuery(const Sphere& sphere, unsigned long mask) 00541 { 00542 // TODO 00543 return NULL; 00544 } 00545 //----------------------------------------------------------------------- 00546 RaySceneQuery* BspSceneManager:: 00547 createRayQuery(const Ray& ray, unsigned long mask) 00548 { 00549 // TODO 00550 return NULL; 00551 } 00552 //----------------------------------------------------------------------- 00553 IntersectionSceneQuery* BspSceneManager:: 00554 createIntersectionQuery(unsigned long mask) 00555 { 00556 BspIntersectionSceneQuery* q = new BspIntersectionSceneQuery(this); 00557 q->setQueryMask(mask); 00558 return q; 00559 } 00560 //----------------------------------------------------------------------- 00561 //----------------------------------------------------------------------- 00562 BspIntersectionSceneQuery::BspIntersectionSceneQuery(SceneManager* creator) 00563 : DefaultIntersectionSceneQuery(creator) 00564 { 00565 // Add bounds fragment type 00566 mSupportedWorldFragments.insert(SceneQuery::WFT_PLANE_BOUNDED_REGION); 00567 00568 } 00569 void BspIntersectionSceneQuery::execute(IntersectionSceneQueryListener* listener) 00570 { 00571 /* 00572 Go through each leaf node in BspLevel and check movables against each other and world 00573 Issue: some movable-movable intersections could be reported twice if 2 movables 00574 overlap 2 leaves? 00575 */ 00576 BspLevel* lvl = ((BspSceneManager*)mParentSceneMgr)->getLevel(); 00577 BspNode* leaf = lvl->getLeafStart(); 00578 int numLeaves = lvl->getNumLeaves(); 00579 00580 while (numLeaves--) 00581 { 00582 const BspNode::IntersectingObjectSet& objects = leaf->getObjects(); 00583 int numObjects = (int)objects.size(); 00584 00585 BspNode::IntersectingObjectSet::const_iterator a, b, theEnd; 00586 theEnd = objects.end(); 00587 a = objects.begin(); 00588 for (int oi = 0; oi < numObjects; ++oi, ++a) 00589 { 00590 const MovableObject* aObj = *a; 00591 // Skip this object if collision not enabled 00592 if (!(aObj->getQueryFlags() & mQueryMask)) 00593 continue; 00594 00595 if (oi < (numObjects-1)) 00596 { 00597 // Check object against others in this node 00598 b = a; 00599 for (++b; b != theEnd; ++b) 00600 { 00601 const MovableObject* bObj = *b; 00602 // Apply mask to b (both must pass) 00603 if ( bObj->getQueryFlags() & mQueryMask) 00604 { 00605 const AxisAlignedBox& box1 = aObj->getWorldBoundingBox(); 00606 const AxisAlignedBox& box2 = bObj->getWorldBoundingBox(); 00607 00608 if (box1.intersects(box2)) 00609 { 00610 listener->queryResult(const_cast<MovableObject*>(aObj), 00611 const_cast<MovableObject*>(bObj)); // hacky 00612 } 00613 } 00614 } 00615 } 00616 // Check object against brushes 00617 const BspNode::NodeBrushList& brushes = leaf->getSolidBrushes(); 00618 BspNode::NodeBrushList::const_iterator bi, biend; 00619 biend = brushes.end(); 00620 Real radius = aObj->getBoundingRadius(); 00621 const Vector3& pos = aObj->getParentNode()->_getDerivedPosition(); 00622 00623 for (bi = brushes.begin(); bi != biend; ++bi) 00624 { 00625 std::list<Plane>::const_iterator planeit, planeitend; 00626 planeitend = (*bi)->planes.end(); 00627 bool brushIntersect = true; // Assume intersecting for now 00628 00629 for (planeit = (*bi)->planes.begin(); planeit != planeitend; ++planeit) 00630 { 00631 Real dist = planeit->getDistance(pos); 00632 if (dist > radius) 00633 { 00634 // Definitely excluded 00635 brushIntersect = false; 00636 break; 00637 } 00638 } 00639 if (brushIntersect) 00640 { 00641 // report this brush as it's WorldFragment 00642 assert((*bi)->fragment.fragmentType == SceneQuery::WFT_PLANE_BOUNDED_REGION); 00643 listener->queryResult(const_cast<MovableObject*>(aObj), // hacky 00644 const_cast<WorldFragment*>(&((*bi)->fragment))); 00645 } 00646 00647 } 00648 00649 00650 } 00651 00652 ++leaf; 00653 } 00654 00655 00656 00657 } 00658 } 00659
Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:03 2004