void Sector::tryRemoveSpatialComponent(SpatialComponent* sp) { ANKI_ASSERT(sp); // Find sector in spatial auto itsp = sp->getSectorInfo().getBegin(); auto endsp = sp->getSectorInfo().getEnd(); for(; itsp != endsp; ++itsp) { if(*itsp == this) { break; } } if(itsp != endsp) { // Found, remove sp->getSectorInfo().erase(getSceneAllocator(), itsp); auto it = findSpatialComponent(sp); ANKI_ASSERT(it != m_spatials.getEnd()); m_spatials.erase(getSceneAllocator(), it); } else { #if ANKI_ASSERTIONS ANKI_ASSERT(findSpatialComponent(sp) == m_spatials.getEnd()); #endif } }
Error PortalSectorBase::init(const CString& meshFname, Bool isSector) { // Create move component SceneComponent* comp = getSceneAllocator().newInstance<MoveComponent>(this); addComponent(comp, true); // Create portal or sector component if(isSector) { comp = getSceneAllocator().newInstance<SectorComponent>(this); } else { comp = getSceneAllocator().newInstance<PortalComponent>(this); } addComponent(comp, true); // Load mesh MeshLoader loader(&getSceneGraph().getResourceManager()); ANKI_CHECK(loader.load(meshFname)); // Convert Vec3 positions to Vec4 const MeshLoader::Header& header = loader.getHeader(); U vertsCount = header.m_totalVerticesCount; PtrSize vertSize = loader.getVertexSize(); auto alloc = getSceneAllocator(); m_shapeStorageLSpace.create(alloc, vertsCount); m_shapeStorageWSpace.create(alloc, vertsCount); for(U i = 0; i < vertsCount; ++i) { const Vec3& pos = *reinterpret_cast<const Vec3*>(loader.getVertexData() + vertSize * i); m_shapeStorageLSpace[i] = Vec4(pos, 0.0); } // Create shape ConvexHullShape* hull = alloc.newInstance<ConvexHullShape>(); m_shape = hull; hull->initStorage(&m_shapeStorageWSpace[0], vertsCount); updateTransform(Transform::getIdentity()); // Store indices ANKI_ASSERT(header.m_totalIndicesCount * sizeof(U16) == loader.getIndexDataSize()); m_vertIndices.create(alloc, header.m_totalIndicesCount); const U16* indicesIn = reinterpret_cast<const U16*>(loader.getIndexData()); for(U i = 0; i < header.m_totalIndicesCount; ++i) { m_vertIndices[i] = indicesIn[i]; } return ErrorCode::NONE; }
Portal::~Portal() { auto alloc = getSceneAllocator(); // Remove from sectors for(Sector* s : m_sectors) { s->tryRemovePortal(this); } m_sectors.destroy(getSceneAllocator()); }
//============================================================================== void EventManager::deleteEventsMarkedForDeletion() { SceneAllocator<Event> al = getSceneAllocator(); // Gather events for deletion SceneFrameVector<EventsContainer::iterator> forDeletion(getSceneFrameAllocator()); for(EventsContainer::iterator it = events.begin(); it != events.end(); ++it) { Event* event = *it; if(event->isMarkedForDeletion()) { forDeletion.push_back(it); } } // Delete events for(auto it : forDeletion) { Event* event = *it; unregisterEvent(event); al.deleteInstance(event); } }
//============================================================================== void EventManager::deleteEventsMarkedForDeletion() { SceneAllocator<U8> alloc = getSceneAllocator(); // Check if nodes are marked for deletion if(true) { auto it = m_events.getBegin(); auto end = m_events.getEnd(); for(; it != end; ++it) { } } // Gather events for deletion while(m_markedForDeletionCount != 0) { auto it = m_events.getBegin(); auto end = m_events.getEnd(); for(; it != end; ++it) { Event* event = *it; if(event->getMarkedForDeletion()) { unregisterEvent(it); alloc.deleteInstance<Event>(event); --m_markedForDeletionCount; break; } } } }
PortalSectorBase::~PortalSectorBase() { auto alloc = getSceneAllocator(); if(m_shape) { alloc.deleteInstance(m_shape); m_shape = nullptr; } m_shapeStorageLSpace.destroy(alloc); m_shapeStorageWSpace.destroy(alloc); m_vertIndices.destroy(alloc); }
void Sector::tryAddSpatialComponent(SpatialComponent* sp) { ANKI_ASSERT(sp); // Find sector in spatial auto itsp = sp->getSectorInfo().getBegin(); auto endsp = sp->getSectorInfo().getEnd(); for(; itsp != endsp; ++itsp) { if(*itsp == this) { // Found, return ANKI_ASSERT( findSpatialComponent(sp) != m_spatials.getEnd() && "Spatial has reference to sector but sector not"); return; } } ANKI_ASSERT(findSpatialComponent(sp) == m_spatials.getEnd()); m_spatials.pushBack(getSceneAllocator(), sp); sp->getSectorInfo().pushBack(getSceneAllocator(), this); }
//============================================================================== 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 Portal::tryRemoveSector(Sector* sector) { ANKI_ASSERT(sector); auto it = m_sectors.getBegin(); auto end = m_sectors.getEnd(); for(; it != end; ++it) { if(*it == sector) { m_sectors.erase(getSceneAllocator(), it); break; } } }
void Sector::tryRemovePortal(Portal* portal) { ANKI_ASSERT(portal); auto it = m_portals.getBegin(); auto end = m_portals.getEnd(); for(; it != end; ++it) { if(*it == portal) { m_portals.erase(getSceneAllocator(), it); break; } } }
void Sector::tryAddPortal(Portal* portal) { ANKI_ASSERT(portal); auto it = m_portals.getBegin(); auto end = m_portals.getEnd(); for(; it != end; ++it) { if(*it == portal) { // Already there, return return; } } m_portals.pushBack(getSceneAllocator(), portal); }
void Portal::tryAddSector(Sector* sector) { ANKI_ASSERT(sector); auto it = m_sectors.getBegin(); auto end = m_sectors.getEnd(); for(; it != end; ++it) { if(*it == sector) { // Already there, return return; } } m_sectors.pushBack(getSceneAllocator(), sector); }
Sector::~Sector() { auto alloc = getSceneAllocator(); // Remove portals for(Portal* p : m_portals) { p->tryRemoveSector(this); } m_portals.destroy(alloc); // Remove spatials U spatialsCount = m_spatials.getSize(); while(spatialsCount-- != 0) // Use counter { tryRemoveSpatialComponent(m_spatials.getFront()); } }
//============================================================================== SceneNode::~SceneNode() { auto alloc = getSceneAllocator(); auto it = m_components.begin(); auto end = m_components.begin() + m_componentsCount; for(; it != end; ++it) { SceneComponent* comp = *it; if(comp->getAutomaticCleanup()) { alloc.deleteInstance(comp); } } Base::destroy(alloc); m_name.destroy(alloc); m_components.destroy(alloc); }
//============================================================================== void SceneNode::addComponent(SceneComponent* comp, Bool transferOwnership) { ANKI_ASSERT(comp); #if ANKI_ASSERTIONS Error err = iterateComponents([&](const SceneComponent& bcomp) -> Error { ANKI_ASSERT(comp != &bcomp); return ErrorCode::NONE; }); (void)err; #endif if(m_components.getSize() < m_componentsCount + 1u) { // Not enough room const U extra = 2; m_components.resize(getSceneAllocator(), m_componentsCount + 1 + extra); } m_components[m_componentsCount++] = comp; comp->setAutomaticCleanup(transferOwnership); }
//============================================================================== EventManager::EventManager(SceneGraph* scene_) : scene(scene_), events(getSceneAllocator()) {}
//============================================================================== void EventManager::unregisterEvent(EventsContainer::Iterator it) { ANKI_ASSERT(it != m_events.getEnd()); m_events.erase(getSceneAllocator(), it); }
//============================================================================== void EventManager::registerEvent(Event* event) { ANKI_ASSERT(event); m_events.pushBack(getSceneAllocator(), event); }
//============================================================================== Error SceneNode::init(const CString& name) { m_name.create(getSceneAllocator(), name); return ErrorCode::NONE; }