void SectorGroup::findVisibleSectors(const FrustumComponent& frc, const SoftwareRasterizer* r, List<const Sector*>& visibleSectors, U& spatialsCount) const { // Find the sector the eye is in Sphere eye(frc.getFrustumOrigin(), frc.getFrustum().getNear()); Bool eyeInsideASector = false; Sector* sectorEyeIsInside = nullptr; iterateSceneSectors(*m_scene, [&](Sector& sector) -> Bool { Bool collide = testCollisionShapes(eye, sector.m_aabb); if(collide) { collide = testCollisionShapes(eye, sector.getBoundingShape()); } if(collide) { eyeInsideASector = true; sectorEyeIsInside = §or; return true; } return false; }); if(!eyeInsideASector) { // eye outside all sectors, find those the frustum collides iterateSceneSectors(*m_scene, [&](Sector& sector) -> Bool { if(frc.insideFrustum(sector.getBoundingShape())) { findVisibleSectorsInternal(frc, sector, r, visibleSectors, spatialsCount); } return false; }); } else { // eye inside a sector findVisibleSectorsInternal(frc, *sectorEyeIsInside, r, visibleSectors, spatialsCount); } }
void SectorGroup::findVisibleSectorsInternal(const FrustumComponent& frc, const Sector& s, const SoftwareRasterizer* r, List<const Sector*>& visibleSectors, U& spatialsCount) const { auto alloc = m_scene->getFrameAllocator(); // Check if "s" is already there auto it = visibleSectors.getBegin(); auto end = visibleSectors.getEnd(); for(; it != end; ++it) { if(*it == &s) { // Sector already there, skip return; } } // Sector not in the list, push it visibleSectors.pushBack(alloc, &s); spatialsCount += s.m_spatials.getSize(); // Check visible portals auto itp = s.m_portals.getBegin(); auto itend = s.m_portals.getEnd(); for(; itp != itend; ++itp) { const Portal& p = *(*itp); if(frc.insideFrustum(p.getBoundingShape()) && (r == nullptr || r->visibilityTest(p.getBoundingShape(), p.m_aabb))) { auto it = p.m_sectors.getBegin(); auto end = p.m_sectors.getEnd(); for(; it != end; ++it) { if(*it != &s) { findVisibleSectorsInternal(frc, *(*it), r, visibleSectors, spatialsCount); } } } } }