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 SceneDebugDrawer::draw(FrustumComponent& fr) const { const Frustum& fs = fr.getFrustum(); m_dbg->setColor(Vec3(1.0, 1.0, 0.0)); CollisionDebugDrawer coldraw(m_dbg); fs.accept(coldraw); }
//============================================================================== Error Camera::init(const CString& name, Frustum* frustum) { ANKI_CHECK(SceneNode::init(name)); SceneComponent* comp; // Move component comp = getSceneAllocator().newInstance<MoveComponent>(this); addComponent(comp, true); // Feedback component comp = getSceneAllocator().newInstance<CameraMoveFeedbackComponent>(this); addComponent(comp, true); // Frustum component FrustumComponent* frc = getSceneAllocator().newInstance<FrustumComponent>(this, frustum); frc->setEnabledVisibilityTests( FrustumComponentVisibilityTestFlag::RENDER_COMPONENTS | FrustumComponentVisibilityTestFlag::LIGHT_COMPONENTS | FrustumComponentVisibilityTestFlag::LENS_FLARE_COMPONENTS | FrustumComponentVisibilityTestFlag::REFLECTION_PROBES | FrustumComponentVisibilityTestFlag::REFLECTION_PROXIES | FrustumComponentVisibilityTestFlag::OCCLUDERS); addComponent(frc, true); // Feedback component #2 comp = getSceneAllocator().newInstance<CameraFrustumFeedbackComponent>(this); addComponent(comp, true); // Spatial component comp = getSceneAllocator().newInstance<SpatialComponent>(this, frustum); addComponent(comp, true); return ErrorCode::NONE; }
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); } } } } }