//--------------------------------------------------------------------- void PCZPlaneBoundedVolumeListSceneQuery::execute(SceneQueryListener* listener) { std::set<SceneNode*> checkedSceneNodes; PlaneBoundedVolumeList::iterator pi, piend; piend = mVolumes.end(); for (pi = mVolumes.begin(); pi != piend; ++pi) { PCZSceneNodeList list; //find the nodes that intersect the Plane bounded Volume static_cast<PCZSceneManager*>( mParentSceneMgr ) -> findNodesIn( *pi, list, mStartZone, (PCZSceneNode*)mExcludeNode ); //grab all moveables from the node that intersect... PCZSceneNodeList::iterator it, itend; itend = list.end(); for (it = list.begin(); it != itend; ++it) { // avoid double-check same scene node if (!checkedSceneNodes.insert(*it).second) continue; SceneNode::ObjectIterator oit = (*it) -> getAttachedObjectIterator(); while( oit.hasMoreElements() ) { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && (m->getTypeFlags() & mQueryTypeMask) && m->isInScene() && (*pi).intersects( m->getWorldBoundingBox() ) ) { listener -> queryResult( m ); // deal with attached objects, since they are not directly attached to nodes if (m->getMovableType() == "Entity") { Entity* e = static_cast<Entity*>(m); Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); while(childIt.hasMoreElements()) { MovableObject* c = childIt.getNext(); if (c->getQueryFlags() & mQueryMask && (*pi).intersects( c->getWorldBoundingBox())) { listener->queryResult(c); } } } } } } }//for // reset startzone and exclude node mStartZone = 0; mExcludeNode = 0; }
//--------------------------------------------------------------------- void PCZRaySceneQuery::execute(RaySceneQueryListener* listener) { PCZSceneNodeList list; //find the nodes that intersect the Ray static_cast<PCZSceneManager*>( mParentSceneMgr ) -> findNodesIn( mRay, list, mStartZone, (PCZSceneNode*)mExcludeNode ); //grab all moveables from the node that intersect... PCZSceneNodeList::iterator it = list.begin(); while( it != list.end() ) { SceneNode::ObjectIterator oit = (*it) -> getAttachedObjectIterator(); while( oit.hasMoreElements() ) { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && (m->getTypeFlags() & mQueryTypeMask) && m->isInScene() ) { std::pair<bool, Real> result = mRay.intersects(m->getWorldBoundingBox()); if( result.first ) { listener -> queryResult( m, result.second ); // deal with attached objects, since they are not directly attached to nodes if (m->getMovableType() == "Entity") { Entity* e = static_cast<Entity*>(m); Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); while(childIt.hasMoreElements()) { MovableObject* c = childIt.getNext(); if (c->getQueryFlags() & mQueryMask) { result = mRay.intersects(c->getWorldBoundingBox()); if (result.first) { listener->queryResult(c, result.second); } } } } } } } ++it; } // reset startzone and exclude node mStartZone = 0; mExcludeNode = 0; }
void Octree::_findNodes(const PlaneBoundedVolume &t, PCZSceneNodeList &list, PCZSceneNode *exclude, bool includeVisitors, bool full ) { if ( !full ) { AxisAlignedBox obox; _getCullBounds( &obox ); Intersection isect = intersect( t, obox ); if ( isect == OUTSIDE ) return ; full = ( isect == INSIDE ); } PCZSceneNodeList::iterator it = mNodes.begin(); while ( it != mNodes.end() ) { PCZSceneNode * on = ( *it ); if ( on != exclude && (on->getHomeZone() == mZone || includeVisitors )) { if ( full ) { // make sure the node isn't already on the list list.insert( on ); } else { Intersection nsect = intersect( t, on -> _getWorldAABB() ); if ( nsect != OUTSIDE ) { // make sure the node isn't already on the list list.insert( on ); } } } ++it; } Octree* child; if ( (child=mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) child->_findNodes( t, list, exclude, includeVisitors, full ); if ( (child=mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) child->_findNodes( t, list, exclude, includeVisitors, full ); if ( (child=mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) child->_findNodes( t, list, exclude, includeVisitors, full ); if ( (child=mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) child->_findNodes( t, list, exclude, includeVisitors, full ); if ( (child=mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) child->_findNodes( t, list, exclude, includeVisitors, full ); if ( (child=mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) child->_findNodes( t, list, exclude, includeVisitors, full ); if ( (child=mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) child->_findNodes( t, list, exclude, includeVisitors, full ); if ( (child=mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) child->_findNodes( t, list, exclude, includeVisitors, full ); }
void DefaultZone::_findNodes( const Ray &t, PCZSceneNodeList &list, PortalList &visitedPortals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode *exclude ) { // if this zone has an enclosure, check against the enclosure AABB first if (mEnclosureNode) { std::pair<bool, Real> nsect = t.intersects(mEnclosureNode->_getWorldAABB()); if (!nsect.first) { // AABB of zone does not intersect t, just return. return; } } // check nodes at home in this zone PCZSceneNodeList::iterator it = mHomeNodeList.begin(); while ( it != mHomeNodeList.end() ) { PCZSceneNode * pczsn = *it; if ( pczsn != exclude ) { // make sure node is not already in the list (might have been added in another // zone it was visiting) PCZSceneNodeList::iterator it2 = list.find(pczsn); if (it2 == list.end()) { std::pair<bool, Real> nsect = t.intersects( pczsn -> _getWorldAABB() ); if ( nsect.first ) { list.insert( pczsn ); } } } ++it; } if (includeVisitors) { // check visitor nodes PCZSceneNodeList::iterator iter = mVisitorNodeList.begin(); while ( iter != mVisitorNodeList.end() ) { PCZSceneNode * pczsn = *iter; if ( pczsn != exclude ) { // make sure node is not already in the list (might have been added in another // zone it was visiting) PCZSceneNodeList::iterator it2 = list.find(pczsn); if (it2 == list.end()) { std::pair<bool, Real> nsect = t.intersects( pczsn -> _getWorldAABB() ); if ( nsect.first ) { list.insert( pczsn ); } } } ++iter; } } // if asked to, recurse through portals if (recurseThruPortals) { PortalList::iterator pit = mPortals.begin(); while ( pit != mPortals.end() ) { Portal * portal = *pit; // check portal versus bounding box if (portal->intersects(t)) { // make sure portal hasn't already been recursed through PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); if (pit2 == visitedPortals.end()) { // save portal to the visitedPortals list visitedPortals.push_front(portal); // recurse into the connected zone portal->getTargetZone()->_findNodes(t, list, visitedPortals, includeVisitors, recurseThruPortals, exclude); } } pit++; } } }
//--------------------------------------------------------------------- void PCZIntersectionSceneQuery::execute(IntersectionSceneQueryListener* listener) { typedef std::pair<MovableObject *, MovableObject *> MovablePair; typedef std::set < std::pair<MovableObject *, MovableObject *> > MovableSet; MovableSet set; // Iterate over all movable types Root::MovableObjectFactoryIterator factIt = Root::getSingleton().getMovableObjectFactoryIterator(); while(factIt.hasMoreElements()) { SceneManager::MovableObjectIterator it = mParentSceneMgr->getMovableObjectIterator( factIt.getNext()->getType()); while( it.hasMoreElements() ) { MovableObject * e = it.getNext(); PCZone * zone = ((PCZSceneNode*)(e->getParentSceneNode()))->getHomeZone(); PCZSceneNodeList list; //find the nodes that intersect the AAB static_cast<PCZSceneManager*>( mParentSceneMgr ) -> findNodesIn( e->getWorldBoundingBox(), list, zone, 0 ); //grab all moveables from the node that intersect... PCZSceneNodeList::iterator nit = list.begin(); while( nit != list.end() ) { SceneNode::ObjectIterator oit = (*nit) -> getAttachedObjectIterator(); while( oit.hasMoreElements() ) { MovableObject * m = oit.getNext(); if( m != e && set.find( MovablePair(e,m)) == set.end() && set.find( MovablePair(m,e)) == set.end() && (m->getQueryFlags() & mQueryMask) && (m->getTypeFlags() & mQueryTypeMask) && m->isInScene() && e->getWorldBoundingBox().intersects( m->getWorldBoundingBox() ) ) { listener -> queryResult( e, m ); // deal with attached objects, since they are not directly attached to nodes if (m->getMovableType() == "Entity") { Entity* e2 = static_cast<Entity*>(m); Entity::ChildObjectListIterator childIt = e2->getAttachedObjectIterator(); while(childIt.hasMoreElements()) { MovableObject* c = childIt.getNext(); if (c->getQueryFlags() & mQueryMask && e->getWorldBoundingBox().intersects( c->getWorldBoundingBox() )) { listener->queryResult(e, c); } } } } set.insert( MovablePair(e,m) ); } ++nit; } } } }