/** Update all the entities cerrently existing in the stage. This function must be called once per frame. - Basic steps - 1. Call BaseEntity::UpdateBaseEntity( dt ) for each base entity - 2. Save positions of copy entities - 3. Run physics simulator - 4. Remove terminated entities from the active list - 5. Call CCopyEntity::Act() for each copy entity except for child entities - 6. Update link to the entity tree node if an entity has changed its position in Act() TODO: Do 5 & 6 in a single loop to update link for each entity right after is Act(). Current code does this in separate loops. */ void EntityManager::UpdateAllEntities( float dt ) { CCopyEntity *pEntity = NULL; CCopyEntity *pPrevEntity = NULL; CCopyEntity *pTouchedEnt = NULL; ONCE( LOG_PRINT( " - updating base entities" ) ); size_t i, num_base_entities = m_vecpBaseEntity.size(); for( i=0; i<num_base_entities; i++ ) { m_vecpBaseEntity[i]->UpdateBaseEntity( dt ); } // save the current entity positions for( pEntity = m_pEntityInUse.get(); pEntity != NULL; pEntity = pEntity->m_pNextRawPtr ) { pEntity->PrevPosition() = pEntity->GetWorldPosition(); } // run physics simulator // entity position may be modified in this call UpdatePhysics( dt ); ONCE( LOG_PRINT( " - updated physics" ) ); // remove terminated entities from the active entity list ReleaseTerminatedEntities(); ONCE( LOG_PRINT( " - removed terminated entities from the active entity list" ) ); // update active entities for( pEntity = this->m_pEntityInUse.get(), pPrevEntity = NULL; pEntity != NULL; pPrevEntity = pEntity, pEntity = pEntity->m_pNextRawPtr ) { // before updating pEntity, check if it has been terminated. if( !pEntity->inuse ) continue; // set the results of physics simulation to // pose, velocity and angular velocity of the entity // if( pEntity->pPhysicsActor && pEntity->GetEntityFlags() & BETYPE_USE_PHYSSIM_RESULTS ) if( 0 < pEntity->m_vecpPhysicsActor.size() && pEntity->GetEntityFlags() & BETYPE_USE_PHYSSIM_RESULTS ) pEntity->UpdatePhysics(); if( pEntity->sState & CESTATE_ATREST ) continue; if( !pEntity->m_pParent || !pEntity->m_pParent->inuse ) { // 'pEntity' has no parent or its parent is already terminated pEntity->pBaseEntity->Act( pEntity ); } if( !pEntity->inuse ) continue; // terminated in its own update routine UpdateEntityAfterMoving( pEntity ); // deal with entities touched during this frame for(int i=0; i<pEntity->vecpTouchedEntity.size(); i++) { pTouchedEnt = pEntity->vecpTouchedEntity[i]; pEntity->pBaseEntity->Touch( pEntity, pTouchedEnt ); if( pTouchedEnt ) pTouchedEnt->pBaseEntity->Touch( pTouchedEnt, pEntity ); } // clear touched entities for the next frame pEntity->vecpTouchedEntity.clear(); } ONCE( LOG_PRINT( " - updated active entities" ) ); // unlink and link the entity in the entity tree if it changed its position /* for( pEntity = m_pEntityInUse.get(); pEntity != NULL; pPrevEntity = pEntity, pEntity = pEntity->m_pNextRawPtr ) { if( !pEntity->inuse ) continue; UpdateEntityAfterMoving(); } */ }