void Sector::deferredUpdate() { // Spatials should get updated for(SpatialComponent* sp : m_spatials) { sp->markForUpdate(); } iterateScenePortals(getSceneGraph(), [&](Portal& portal) -> Bool { Bool collide = testCollisionShapes(m_aabb, portal.m_aabb); if(collide) { collide = testCollisionShapes(*m_shape, portal.getBoundingShape()); } if(collide) { portal.tryAddSector(this); tryAddPortal(&portal); } else { portal.tryRemoveSector(this); tryRemovePortal(&portal); } return false; }); }
void Portal::deferredUpdate() { // Gather the sectors it collides iterateSceneSectors(getSceneGraph(), [&](Sector& sector) -> Bool { Bool collide = testCollisionShapes(m_aabb, sector.m_aabb); // Perform a more detailed test if(collide) { collide = testCollisionShapes(*m_shape, sector.getBoundingShape()); } // Update graphs if(collide) { tryAddSector(§or); sector.tryAddPortal(this); } else { tryRemoveSector(§or); sector.tryRemovePortal(this); } return false; }); }
void SectorGroup::binSpatial(SpatialComponent* sp) { ANKI_ASSERT(sp); // Iterate all sectors and bin the spatial iterateSceneSectors(*m_scene, [&](Sector& sector) -> Bool { Bool collide = false; if(!sp->getSingleSector()) { // Spatial can belong to multiple sectors // Fast test collide = testCollisionShapes(sector.m_aabb, sp->getAabb()); // Detailed test if(collide) { collide = testCollisionShapes(sector.getBoundingShape(), sp->getSpatialCollisionShape()); } } else { // Spatial can belong to one sector // Make sure the origin of the spatial is inside the sector const Vec4& center = sp->getSpatialOrigin(); if(center >= sector.m_aabb.getMin() && center <= sector.m_aabb.getMax()) { collide = true; } // Detailed test const F32 smallf = EPSILON * 10.0; Aabb smallBox(center, center + Vec4(smallf, smallf, smallf, 0.0)); if(collide) { collide = testCollisionShapes(sector.getBoundingShape(), smallBox); } } if(collide) { sector.tryAddSpatialComponent(sp); } else { sector.tryRemoveSpatialComponent(sp); } return false; }); }
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); } }
/// Compound shape. static Bool tcx(const CollisionShape& a, const CollisionShape& b) { Bool inside = false; const CompoundShape& c = dcast<const CompoundShape&>(a); // Use the error to stop the loop Error err = c.iterateShapes([&](const CollisionShape& cs) { if(testCollisionShapes(cs, b)) { inside = true; return ErrorCode::FUNCTION_FAILED; } return ErrorCode::NONE; }); (void)err; return inside; }