void EntitySimulation::prepareEntityForDelete(EntityItemPointer entity) { assert(entity); assert(entity->isDead()); if (entity->isSimulated()) { QMutexLocker lock(&_mutex); entity->clearActions(getThisPointer()); removeEntityInternal(entity); _entitiesToDelete.insert(entity); } }
void PhysicalEntitySimulation::removeEntityInternal(EntityItemPointer entity) { if (entity->isSimulated()) { EntitySimulation::removeEntityInternal(entity); QMutexLocker lock(&_mutex); _entitiesToAddToPhysics.remove(entity); EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo()); if (motionState) { _outgoingChanges.remove(motionState); _entitiesToRemoveFromPhysics.insert(entity); } else { _entitiesToDelete.insert(entity); } } }
void EntitySimulation::changeEntity(EntityItemPointer entity) { QMutexLocker lock(&_mutex); assert(entity); if (!entity->isSimulated()) { // This entity was either never added to the simulation or has been removed // (probably for pending delete), so we don't want to keep a pointer to it // on any internal lists. return; } // Although it is not the responsibility of the EntitySimulation to sort the tree for EXTERNAL changes // it IS responsibile for triggering deletes for entities that leave the bounds of the domain, hence // we must check for that case here, however we rely on the change event to have set DIRTY_POSITION flag. bool wasRemoved = false; uint32_t dirtyFlags = entity->getDirtyFlags(); if (dirtyFlags & Simulation::DIRTY_POSITION) { AACube domainBounds(glm::vec3((float)-HALF_TREE_SCALE), (float)TREE_SCALE); bool success; AACube newCube = entity->getQueryAACube(success); if (success && !domainBounds.touches(newCube)) { qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds."; entity->die(); prepareEntityForDelete(entity); wasRemoved = true; } } if (!wasRemoved) { if (dirtyFlags & Simulation::DIRTY_LIFETIME) { if (entity->isMortal()) { _mortalEntities.insert(entity); quint64 expiry = entity->getExpiry(); if (expiry < _nextExpiry) { _nextExpiry = expiry; } } else { _mortalEntities.remove(entity); } entity->clearDirtyFlags(Simulation::DIRTY_LIFETIME); } if (entity->needsToCallUpdate()) { _entitiesToUpdate.insert(entity); } else { _entitiesToUpdate.remove(entity); } changeEntityInternal(entity); } }