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